Merge lp:~canonical-ca-hackers/ubuntu-recommender/933884-delete-old-recommendations into lp:ubuntu-recommender

Proposed by Łukasz Czyżykowski
Status: Merged
Approved by: Michael Nelson
Approved revision: 65
Merged at revision: 49
Proposed branch: lp:~canonical-ca-hackers/ubuntu-recommender/933884-delete-old-recommendations
Merge into: lp:ubuntu-recommender
Diff against target: 130 lines (+99/-1)
2 files modified
src/recommender/management/commands/recommendation_cleanup.py (+57/-0)
src/recommender/tests/test_commands.py (+42/-1)
To merge this branch: bzr merge lp:~canonical-ca-hackers/ubuntu-recommender/933884-delete-old-recommendations
Reviewer Review Type Date Requested Status
Michael Nelson (community) Approve
Review via email: mp+95582@code.launchpad.net

Commit message

Added recommendation_cleanup management command.

Description of the change

Overview
========
This branch adds a management command to clean up old Recommendation objects which doesn't have any feedback. By default, recommendation created more than 30 days ago are deleted, but this can be specified on the command line.

$ python manage.py recommendation_cleanup [30]

To post a comment you must log in.
Revision history for this message
Michael Nelson (michael.nelson) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== added file 'src/recommender/management/commands/recommendation_cleanup.py'
2--- src/recommender/management/commands/recommendation_cleanup.py 1970-01-01 00:00:00 +0000
3+++ src/recommender/management/commands/recommendation_cleanup.py 2012-03-02 15:02:42 +0000
4@@ -0,0 +1,57 @@
5+# -*- coding: utf-8 -*-
6+# This file is part of the Ubuntu Recommender
7+# Copyright (C) 2011-2012 Canonical Ltd.
8+#
9+# This program is free software: you can redistribute it and/or modify
10+# it under the terms of the GNU Affero General Public License as
11+# published by the Free Software Foundation, either version 3 of the
12+# License, or (at your option) any later version.
13+#
14+# This program is distributed in the hope that it will be useful,
15+# but WITHOUT ANY WARRANTY; without even the implied warranty of
16+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17+# GNU Affero General Public License for more details.
18+#
19+# You should have received a copy of the GNU Affero General Public License
20+# along with this program. If not, see <http://www.gnu.org/licenses/>.
21+from __future__ import absolute_import
22+
23+__metaclass__ = type
24+__all__ = ['Command']
25+
26+import logging
27+
28+from datetime import date, timedelta
29+
30+from django.core.management.base import BaseCommand
31+
32+from recommender.models import AppRecommendation, UserRecommendation
33+
34+
35+class Command(BaseCommand):
36+
37+ args = "<optional number of days>"
38+ help = "Removes staled recommendation objects."
39+
40+ def handle(self, *args, **options):
41+ try:
42+ days = float(args[0])
43+ except (IndexError, ValueError):
44+ days = 30
45+
46+ log = logging.getLogger('recommender.recommendation_cleanup')
47+ month_ago = date.today() - timedelta(days=days)
48+
49+ log.info("Cleaning up old AppRecommendations")
50+ to_delete_qs = AppRecommendation.objects.filter(
51+ date_created__lt=month_ago, feedback__isnull=True)
52+ deleted_count = to_delete_qs.count()
53+ to_delete_qs.delete()
54+ log.debug("Removed %d AppRecommendation objects", deleted_count)
55+
56+ log.info("Cleaning up old UserRecommendation")
57+ to_delete_qs = UserRecommendation.objects.filter(
58+ date_created__lt=month_ago, feedback__isnull=True)
59+ deleted_count = to_delete_qs.count()
60+ to_delete_qs.delete()
61+ log.debug("Removed %d UserRecommendation objects", deleted_count)
62
63=== modified file 'src/recommender/tests/test_commands.py'
64--- src/recommender/tests/test_commands.py 2012-03-02 13:12:27 +0000
65+++ src/recommender/tests/test_commands.py 2012-03-02 15:02:42 +0000
66@@ -24,11 +24,12 @@
67 'ImportRnRDataTestCase',
68 'SlopeOneBootstrapTestCase',
69 'SlopeOneUpdateTestCase',
70+ 'RecommendationCleanupTestCase',
71 ]
72
73 import sys
74 from cStringIO import StringIO
75-from datetime import date
76+from datetime import date, datetime, timedelta
77
78 from django.core.management import call_command
79 from django_factory import (
80@@ -42,6 +43,8 @@
81 PersonIdentification,
82 Package,
83 SlopeOneFrequency,
84+ AppRecommendation,
85+ UserRecommendation,
86 )
87 from recommender.management.commands.import_rnr_data import (
88 RatingsAndReviewsAPI,
89@@ -199,3 +202,41 @@
90 # Not 4/3 because user_2 hasn't rated item_3
91 self.assertEqual(2,
92 SlopeOneFrequency.objects.filter(package_1=item_4).count())
93+
94+
95+class RecommendationCleanupTestCase(TransactionTestCase):
96+
97+ def test_running_command_removes_stale_app_recommendations(self):
98+ month_ago = datetime.utcnow() - timedelta(days=31)
99+ self.factory.make(3, AppRecommendation,
100+ date_created=month_ago)
101+ self.factory.make_one(AppRecommendation, feedback=1,
102+ date_created=month_ago)
103+
104+ self.factory.make_one(AppRecommendation)
105+
106+ call_command('recommendation_cleanup')
107+
108+ self.assertEqual(2, AppRecommendation.objects.count())
109+
110+ def test_running_command_removes_stale_user_recommendations(self):
111+ month_ago = datetime.utcnow() - timedelta(days=31)
112+ self.factory.make(3, UserRecommendation,
113+ date_created=month_ago)
114+ self.factory.make_one(UserRecommendation, feedback=1,
115+ date_created=month_ago)
116+
117+ self.factory.make_one(UserRecommendation)
118+
119+ call_command('recommendation_cleanup')
120+
121+ self.assertEqual(2, UserRecommendation.objects.count())
122+
123+ def test_running_command_takes_into_account_passed_number_of_days(self):
124+ self.factory.make_one(
125+ AppRecommendation,
126+ date_created=(datetime.utcnow() - timedelta(days=11)))
127+
128+ call_command('recommendation_cleanup', 10)
129+
130+ self.assertEqual(0, AppRecommendation.objects.count())

Subscribers

People subscribed via source and target branches