|
@@ -17,6 +17,10 @@ use Composer\Package\PackageInterface;
|
|
use Composer\Repository\RepositoryInterface;
|
|
use Composer\Repository\RepositoryInterface;
|
|
use Composer\Repository\InvalidRepositoryException;
|
|
use Composer\Repository\InvalidRepositoryException;
|
|
use Composer\Util\ErrorHandler;
|
|
use Composer\Util\ErrorHandler;
|
|
|
|
+use Composer\Util\RemoteFilesystem;
|
|
|
|
+use Composer\Json\JsonFile;
|
|
|
|
+use Composer\Config;
|
|
|
|
+use Composer\IO\IOInterface;
|
|
use Packagist\WebBundle\Entity\Author;
|
|
use Packagist\WebBundle\Entity\Author;
|
|
use Packagist\WebBundle\Entity\Package;
|
|
use Packagist\WebBundle\Entity\Package;
|
|
use Packagist\WebBundle\Entity\Tag;
|
|
use Packagist\WebBundle\Entity\Tag;
|
|
@@ -85,8 +89,9 @@ class Updater
|
|
* @param int $flags a few of the constants of this class
|
|
* @param int $flags a few of the constants of this class
|
|
* @param \DateTime $start
|
|
* @param \DateTime $start
|
|
*/
|
|
*/
|
|
- public function update(Package $package, RepositoryInterface $repository, $flags = 0, \DateTime $start = null)
|
|
|
|
|
|
+ public function update(IOInterface $io, Config $config, Package $package, RepositoryInterface $repository, $flags = 0, \DateTime $start = null)
|
|
{
|
|
{
|
|
|
|
+ $rfs = new RemoteFilesystem($io, $config);
|
|
$blacklist = '{^symfony/symfony (2.0.[456]|dev-charset|dev-console)}i';
|
|
$blacklist = '{^symfony/symfony (2.0.[456]|dev-charset|dev-console)}i';
|
|
|
|
|
|
if (null === $start) {
|
|
if (null === $start) {
|
|
@@ -162,6 +167,10 @@ class Updater
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ if (preg_match('{^(?:git@|https?://)github.com[:/]([^/]+)/(.+?)(?:\.git|/)?$}i', $package->getRepository(), $match)) {
|
|
|
|
+ $this->updateGitHubInfo($rfs, $package, $match[1], $match[2]);
|
|
|
|
+ }
|
|
|
|
+
|
|
$package->setUpdatedAt(new \DateTime);
|
|
$package->setUpdatedAt(new \DateTime);
|
|
$package->setCrawledAt(new \DateTime);
|
|
$package->setCrawledAt(new \DateTime);
|
|
$em->flush();
|
|
$em->flush();
|
|
@@ -380,4 +389,69 @@ class Updater
|
|
|
|
|
|
return true;
|
|
return true;
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ private function updateGitHubInfo(RemoteFilesystem $rfs, Package $package, $owner, $repo)
|
|
|
|
+ {
|
|
|
|
+ $baseApiUrl = 'https://api.github.com/repos/'.$owner.'/'.$repo;
|
|
|
|
+
|
|
|
|
+ try {
|
|
|
|
+ $repoData = JsonFile::parseJson($rfs->getContents('github.com', $baseApiUrl, false), $baseApiUrl);
|
|
|
|
+ $opts = ['http' => ['header' => ['Accept: application/vnd.github.v3.html']]];
|
|
|
|
+ $readme = $rfs->getContents('github.com', $baseApiUrl.'/readme', false, $opts);
|
|
|
|
+ } catch (\Exception $e) {
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (!empty($readme)) {
|
|
|
|
+ $config = \HTMLPurifier_Config::createDefault();
|
|
|
|
+ $config->set('HTML.Allowed', 'a[href|target|rel|id],strong,b,em,i,strike,pre,code,p,ol,ul,li,br,h1,h2,h3,img[src|title|alt|width|height|style]');
|
|
|
|
+ $config->set('Attr.EnableID', true);
|
|
|
|
+ $config->set('Attr.AllowedFrameTargets', ['_blank']);
|
|
|
|
+ $purifier = new \HTMLPurifier($config);
|
|
|
|
+ $readme = $purifier->purify($readme);
|
|
|
|
+
|
|
|
|
+ $dom = new \DOMDocument();
|
|
|
|
+ $dom->loadHTML('<?xml encoding="UTF-8">' . $readme);
|
|
|
|
+
|
|
|
|
+ // Links can not be trusted
|
|
|
|
+ $links = $dom->getElementsByTagName('a');
|
|
|
|
+ foreach ($links as $link) {
|
|
|
|
+ $link->setAttribute('rel', 'nofollow');
|
|
|
|
+ if ('#' === substr($link->getAttribute('href'), 0, 1)) {
|
|
|
|
+ $link->setAttribute('href', '#user-content-'.substr($link->getAttribute('href'), 1));
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // remove first title as it's usually the project name which we don't need
|
|
|
|
+ if ($dom->getElementsByTagName('h1')->length) {
|
|
|
|
+ $first = $dom->getElementsByTagName('h1')->item(0);
|
|
|
|
+ $first->parentNode->removeChild($first);
|
|
|
|
+ } elseif ($dom->getElementsByTagName('h2')->length) {
|
|
|
|
+ $first = $dom->getElementsByTagName('h2')->item(0);
|
|
|
|
+ $first->parentNode->removeChild($first);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ $readme = $dom->saveHTML();
|
|
|
|
+ $readme = substr($readme, strpos($readme, '<body>')+6);
|
|
|
|
+ $readme = substr($readme, 0, strrpos($readme, '</body>'));
|
|
|
|
+
|
|
|
|
+ $package->setReadme($readme);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (!empty($repoData['language'])) {
|
|
|
|
+ $package->setLanguage($repoData['language']);
|
|
|
|
+ }
|
|
|
|
+ if (!empty($repoData['stargazers_count'])) {
|
|
|
|
+ $package->setGitHubStars($repoData['stargazers_count']);
|
|
|
|
+ }
|
|
|
|
+ if (!empty($repoData['subscribers_count'])) {
|
|
|
|
+ $package->setGitHubWatches($repoData['subscribers_count']);
|
|
|
|
+ }
|
|
|
|
+ if (!empty($repoData['network_count'])) {
|
|
|
|
+ $package->setGitHubForks($repoData['network_count']);
|
|
|
|
+ }
|
|
|
|
+ if (!empty($repoData['open_issues_count'])) {
|
|
|
|
+ $package->setGitHubOpenIssues($repoData['open_issues_count']);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
}
|
|
}
|