Browse Source

Move downloads functionality into a manager class.

ajshort 12 years ago
parent
commit
8fae17c95a

+ 2 - 9
src/Packagist/WebBundle/Controller/ApiController.php

@@ -170,6 +170,7 @@ class ApiController extends Controller
     protected function trackDownload($id, $vid, $ip)
     {
         $redis = $this->get('snc_redis.default');
+        $manager = $this->get('packagist.download_manager');
 
         $throttleKey = 'dl:'.$id.':'.$ip.':'.date('Ymd');
         $requests = $redis->incr($throttleKey);
@@ -177,15 +178,7 @@ class ApiController extends Controller
             $redis->expire($throttleKey, 86400);
         }
         if ($requests <= 10) {
-            $redis->incr('downloads');
-
-            $redis->incr('dl:'.$id);
-            $redis->incr('dl:'.$id.':'.date('Ym'));
-            $redis->incr('dl:'.$id.':'.date('Ymd'));
-
-            $redis->incr('dl:'.$id.'-'.$vid);
-            $redis->incr('dl:'.$id.'-'.$vid.':'.date('Ym'));
-            $redis->incr('dl:'.$id.'-'.$vid.':'.date('Ymd'));
+            $manager->addDownload($id, $vid);
         }
     }
 

+ 9 - 12
src/Packagist/WebBundle/Controller/Controller.php

@@ -21,24 +21,21 @@ class Controller extends BaseController
 {
     protected function getPackagesMetadata($packages)
     {
-        $metadata = null;
         try {
-            $dlKeys = array();
+            $ids = array();
+
             foreach ($packages as $package) {
-                $id = $package instanceof \Solarium_Document_ReadOnly ? $package->id : $package->getId();
-                $dlKeys[$id] = 'dl:'.$id;
+                $ids[] = $package instanceof \Solarium_Document_ReadOnly ? $package->id : $package->getId();
             }
-            if (!$dlKeys) {
-                return $metadata;
+
+            if (!$ids) {
+                return;
             }
-            $res = array_map('intval', $this->get('snc_redis.default')->mget(array_values($dlKeys)));
 
-            $metadata = array(
-                'downloads' => array_combine(array_keys($dlKeys), $res),
-                'favers' => $this->get('packagist.favorite_manager')->getFaverCounts(array_keys($dlKeys)),
+            return array(
+                'downloads' => $this->get('packagist.download_manager')->getPackagesDownloads($ids),
+                'favers' => $this->get('packagist.favorite_manager')->getFaverCounts($ids),
             );
         } catch (\Predis\Connection\ConnectionException $e) {}
-
-        return $metadata;
     }
 }

+ 4 - 14
src/Packagist/WebBundle/Controller/WebController.php

@@ -469,17 +469,9 @@ class WebController extends Controller
 
         $data = array('package' => $package, 'version' => $version);
 
-        $id = $package->getId();
-
         try {
-            /** @var $redis \Snc\RedisBundle\Client\Phpredis\Client */
-            $redis = $this->get('snc_redis.default');
-            $counts = $redis->mget('dl:'.$id, 'dl:'.$id.':'.date('Ym'), 'dl:'.$id.':'.date('Ymd'));
-            $data['downloads'] = array(
-                'total' => $counts[0] ?: 0,
-                'monthly' => $counts[1] ?: 0,
-                'daily' => $counts[2] ?: 0,
-            );
+            $data['downloads'] = $this->get('packagist.download_manager')->getDownloads($package);
+
             if ($this->getUser()) {
                 $data['is_favorite'] = $this->get('packagist.favorite_manager')->isMarked($this->getUser(), $package);
             }
@@ -870,15 +862,13 @@ class WebController extends Controller
             }
 
             try {
-                /** @var $redis \Snc\RedisBundle\Client\Phpredis\Client */
-                $redis = $this->get('snc_redis.default');
-                $downloads = $redis->get('dl:'.$package->getId());
+                $downloads = $this->get('packagist.download_manager')->getDownloads($package);
             } catch (ConnectionException $e) {
                 return;
             }
 
             // more than 50 downloads = established package, do not allow deletion by maintainers
-            if ($downloads > 50) {
+            if ($downloads['total'] > 50) {
                 return;
             }
         }

+ 104 - 0
src/Packagist/WebBundle/Model/DownloadManager.php

@@ -0,0 +1,104 @@
+<?php
+
+/*
+ * This file is part of Packagist.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *     Nils Adermann <naderman@naderman.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Packagist\WebBundle\Model;
+
+use Packagist\WebBundle\Entity\Package;
+use Packagist\WebBundle\Entity\Version;
+use Predis\Client;
+
+/**
+ * Manages the download counts for packages.
+ */
+class DownloadManager
+{
+
+    protected $redis;
+
+    public function __construct(Client $redis)
+    {
+        $this->redis = $redis;
+    }
+
+    /**
+     * Gets the total, monthly, and daily download counts for a package.
+     *
+     * @param \Packagist\WebBundle\Entity\Package|int $package
+     * @return array
+     */
+    public function getDownloads($package)
+    {
+        if ($package instanceof Package) {
+            $package = $package->getId();
+        }
+
+        $counts = $this->redis->mget(
+            'dl:' . $package,
+            'dl:' . $package.':'.date('Ym'),
+            'dl:' . $package.':'.date('Ymd')
+        );
+
+        return array(
+            'total' => (int) $counts[0] ?: 0,
+            'monthly' => (int) $counts[1] ?: 0,
+            'daily' => (int)$counts[2] ?: 0,
+        );
+    }
+
+    /**
+     * Gets total download counts for multiple package IDs.
+     *
+     * @param array $packageIds
+     * @return array a map of package ID to download count
+     */
+    public function getPackagesDownloads(array $packageIds)
+    {
+        $keys = array();
+
+        foreach ($packageIds as $id) {
+            $keys[$id] = 'dl:'.$id;
+        }
+
+        $res = array_map('intval', $this->redis->mget(array_values($keys)));
+        return array_combine(array_keys($keys), $res);
+    }
+
+    /**
+     * Tracks a new download by updating the relevant keys.
+     *
+     * @param \Packagist\WebBundle\Entity\Package|int $package
+     * @param \Packagist\WebBundle\Entity\Version|int $version
+     */
+    public function addDownload($package,  $version)
+    {
+        $redis = $this->redis;
+
+        if ($package instanceof Package) {
+            $package = $package->getId();
+        }
+
+        if ($version instanceof Version) {
+            $version = $version->getId();
+        }
+
+        $redis->incr('downloads');
+
+        $redis->incr('dl:'.$package);
+        $redis->incr('dl:'.$package.':'.date('Ym'));
+        $redis->incr('dl:'.$package.':'.date('Ymd'));
+
+        $redis->incr('dl:'.$package.'-'.$version);
+        $redis->incr('dl:'.$package.'-'.$version.':'.date('Ym'));
+        $redis->incr('dl:'.$package.'-'.$version.':'.date('Ymd'));
+    }
+
+}

+ 5 - 0
src/Packagist/WebBundle/Resources/config/services.yml

@@ -60,6 +60,11 @@ services:
         arguments:
             - 'packagist_oauth_user_registration'
 
+    packagist.download_manager:
+        class: Packagist\WebBundle\Model\DownloadManager
+        arguments:
+            - @snc_redis.default_client
+
     packagist.favorite_manager:
         class: Packagist\WebBundle\Model\FavoriteManager
         arguments: