diff --git a/src/recommender.py b/src/recommender.py
index 8e11bdd..48a42c7 100644
--- a/src/recommender.py
+++ b/src/recommender.py
@@ -49,7 +49,7 @@ class RecommendationResult:
Return prediction based on recommendation size (number of items).
"""
sorted_result = sorted(self.item_score.items(), key=itemgetter(1))
- return reversed(sorted_result[:size])
+ return reversed(sorted_result[-size:])
class Recommender:
"""
diff --git a/src/strategy.py b/src/strategy.py
index 2171e75..18c6e38 100644
--- a/src/strategy.py
+++ b/src/strategy.py
@@ -20,6 +20,7 @@ __license__ = """
along with this program. If not, see .
"""
+import string
import os, re
import xapian
from data import *
@@ -181,7 +182,8 @@ class AxiContentBasedStrategy(RecommendationStrategy):
Perform recommendation strategy.
"""
profile = user.axi_tag_profile(rec.items_repository,50)
- query = xapian.Query(xapian.Query.OP_OR,profile)
+ #profile_str = string.join(list(profile),' ')
+ query = xapian.Query(xapian.Query.OP_OR,list(profile))
enquire = xapian.Enquire(rec.items_repository)
enquire.set_query(query)
@@ -200,13 +202,17 @@ class CollaborativeStrategy(RecommendationStrategy):
"""
Colaborative recommendation strategy.
"""
+ def __init__(self):
+ self.description = "Collaborative"
+
#def run(self,rec,user,similarity_measure):
def run(self,rec,user):
"""
Perform recommendation strategy.
"""
profile = user.maximal_pkg_profile()
- query = xapian.Query(xapian.Query.OP_OR,profile)
+ #profile_str = string.join(list(profile),' ')
+ query = xapian.Query(xapian.Query.OP_OR,list(profile))
enquire = xapian.Enquire(rec.users_repository)
enquire.set_query(query)
@@ -236,6 +242,9 @@ class KnowledgeBasedStrategy(RecommendationStrategy):
"""
Knowledge-based recommendation strategy.
"""
+ def __init__(self):
+ self.description = "Knowledge-based"
+
def run(self,user,knowledge_repository):
"""
Perform recommendation strategy.
@@ -247,6 +256,9 @@ class DemographicStrategy(RecommendationStrategy):
"""
Recommendation strategy based on demographic data.
"""
+ def __init__(self):
+ self.description = "Demographic"
+
def run(self,user,items_repository):
"""
Perform recommendation strategy.
diff --git a/src/user.py b/src/user.py
index a25bbb2..40ce349 100644
--- a/src/user.py
+++ b/src/user.py
@@ -123,12 +123,17 @@ class User:
cache = apt.Cache()
old_profile_size = len(self.pkg_profile)
for p in self.pkg_profile[:]: #iterate list copy
- pkg = cache[p]
- if pkg.candidate:
- for dep in pkg.candidate.dependencies:
- for or_dep in dep.or_dependencies:
- if or_dep.name in self.pkg_profile:
- self.pkg_profile.remove(or_dep.name)
+ try:
+ if cache.has_key(p):
+ pkg = cache[p]
+ if pkg.candidate:
+ for dep in pkg.candidate.dependencies:
+ for or_dep in dep.or_dependencies:
+ if or_dep.name in self.pkg_profile:
+ self.pkg_profile.remove(or_dep.name)
+ except:
+ logging.debug("Disconsidering package not found in cache: %s"
+ % p)
profile_size = len(self.pkg_profile)
logging.info("Reduced packages profile size from %d to %d." %
(old_profile_size, profile_size))
@@ -157,9 +162,14 @@ class LocalSystem(User):
cache = apt.Cache()
old_profile_size = len(self.pkg_profile)
for p in self.pkg_profile[:]: #iterate list copy
- pkg = cache[p]
- if pkg.is_auto_installed:
- self.pkg_profile.remove(p)
+ try:
+ if cache.has_key(p):
+ pkg = cache[p]
+ if pkg.is_auto_installed:
+ self.pkg_profile.remove(p)
+ except:
+ logging.debug("Disconsidering package not found in cache: %s"
+ % p)
profile_size = len(self.pkg_profile)
logging.info("Reduced packages profile size from %d to %d." %
(old_profile_size, profile_size))
diff --git a/src/web/server.py b/src/web/server.py
index 3103f78..2bad012 100755
--- a/src/web/server.py
+++ b/src/web/server.py
@@ -11,119 +11,117 @@ from config import *
from recommender import *
from user import *
-def add_global_hook():
- g = web.storage({"counter": "1"})
- def _wrapper(handler):
- web.ctx.globals = g
- return handler()
- return _wrapper
-
-class Index:
- def GET(self):
- form_action = "/feedback"
- form_method = "post"
- form = self._form()
- return render.index(form_action, form_method, form)
-
- def _form(self):
- send_form = form.Form(
- form.File("pkgs_file", description="Packages list"),
- form.Dropdown('limit', [('5', '05'), ('10', '10'), ('20', '20')],
+class RequestForm(form.Form):
+ def __init__(self):
+ form.Form.__init__(self, \
+ form.File("pkgs_file", description="Upload file"),
+ form.Textarea("pkgs_list", description="Packages",
+ rows="4", cols="40"),
+ form.Dropdown('limit', [(5, '05'), (10, '10'), (20, '20')],
description = "Limit"),
- form.Checkbox("strategy_cb", value="True", checked=False,
+ form.Checkbox("strategy_cb", value=1, checked=False,
description="Content-based"),
- form.Checkbox("strategy_col", value="True", checked=False,
+ form.Checkbox("strategy_col", value=1, checked=False,
description="Collaborative"),
form.Checkbox("strategy_hybrid", value="True", checked=False,
description="Hybrid"),
form.Checkbox("strategy_hybrid_plus", value="True", checked=False,
description="Hybrid plus"),
- validators = [form.Validator("You must select at least one strategy",
- lambda i: i.strategy_cb | i.startegy_col |
- i.strategy_hybrid | i.strategy_hybrid_plus)]
- )
- return send_form()
+ validators = [form.Validator("No packages list provided.",
+ lambda f: f.has_key("pkgs_list") |
+ f.has_key("pkgs_file") ),
+ form.Validator("No strategy selected.",
+ lambda f: f.has_key("strategy_cb") |
+ f.has_key("startegy_col") |
+ f.has_key("strategy_hybrid") |
+ f.has_key("strategy_hybrid_plus")) ])
+
+class FeedbackForm(form.Form):
+ def __init__(self,strategies):
+ desc_dict = {"cta": "Content-based", "col": "Collaborative",
+ "hybrid": "Hybrib", "hybrid_plus": "Hybrid Plus"}
+ fields = []
+ for strategy in strategies:
+ fields.append(form.Radio(desc_dict[strategy],
+ [('1','1 '),('2','2 '),('3','3'),('4','4 '),('5','5')]))
+ form.Form.__init__(self, *fields, validators = [])
+
+class Index:
+ def GET(self):
+ return render.index("/apprec", "post", RequestForm())
+
+class Thanks:
+ def POST(self):
+ return render.thanks()
-class FeedbackForm:
+class AppRecommender:
def POST(self):
- action = "/thanks"
- method = "post"
outputdir = tempfile.mkdtemp(prefix='',dir='./submissions/')
user_id = outputdir.lstrip('./submissions/')
- x = web.input(pkgs_file={})
- f = open(outputdir + "/packages_list", "wb")
- #content = x['pkgs_file'].value
- self.pkgs_list = []
- for line in x['pkgs_file'].file:
- self.pkgs_list.append(line.split()[0])
- f.write(line)
- # while 1:
- # chunk = x['pkgs_file'].file.read(10000)
- # if not chunk:
- # break
- # f.write(chunk)
- f.close()
-
- strategies = []
- if 'strategy_cb' in x: strategies.append("cta")
- if 'strategy_col' in x: strategies.append("col")
- if 'strategy_hybrid' in x: strategies.append("hybrid")
- if 'strategy_hybrid+' in x: strategies.append("hybrid+")
-
- return render.feedbackForm(action, method,
- self._recommends(user_id,strategies),
- self._form())
-
- def _recommends(self,user_id,strategies):
- user = User(dict.fromkeys(self.pkgs_list,1),user_id)
+ request = RequestForm()
+ request_info = web.input(pkgs_file={})
+ if not request.validates(request_info):
+ return render.error(request)
+ else:
+ user_pkgs_list = []
+ if request_info.has_key('pkgs_list'):
+ user_pkgs_list = request_info['pkgs_list'].encode('utf8').split()
+ print user_pkgs_list
+
+ if request_info.has_key('pkgs_file'):
+ f = open(outputdir + "/packages_list", "wb")
+ for line in request_info['pkgs_file'].file:
+ user_pkgs_list.append(line.split()[0])
+ f.write(line)
+ f.close()
+
+ strategies = []
+ if request_info.has_key('strategy_cb'): strategies.append("cta")
+ ### Colaborative strategies can not go online yet
+ if request_info.has_key('strategy_col'): strategies.append("col")
+ if request_info.has_key('strategy_hybrid'):
+ strategies.append("hybrid")
+ if request_info.has_key('strategy_hybrid_plus'):
+ strategies.append("hybrid_plus")
+
+ return render.apprec("/thanks", "post",
+ self._recommends(user_id,user_pkgs_list,
+ strategies, int(request_info['limit'])),
+ FeedbackForm(strategies))
+
+ def _recommends(self,user_id,user_pkgs_list,strategies,limit):
+ user = User(dict.fromkeys(user_pkgs_list,1),user_id)
user.maximal_pkg_profile()
cfg = Config()
rec = Recommender(cfg)
results = dict()
for strategy in strategies:
- eval("rec."+strategy+"(cfg)")
- prediction = rec.get_recommendation(user).get_prediction()
- results[rec.strategy.description] = [result[0] for result in prediction]
- # Colaborative strategies can not go online yet
- results['Hybrid+'] = []
- results['Hybrid'] = []
- results['Collaborative'] = []
+ ### Colaborative strategies can not go online yet
+ #eval("rec."+strategy+"(cfg)")
+ rec.cta(cfg)
+ prediction = rec.get_recommendation(user).get_prediction(limit)
+ results[rec.strategy.description] = \
+ [result[0] for result in prediction]
return results
- def _form(self):
- send_form = form.Form(
- form.Radio('Content-based',
- [('1','1 '),('2','2 '),('3','3 '),('4','4 '),('5','5')]),
- form.Radio('Collaborative',
- [('1','1 '),('2','2 '),('3','3 '),('4','4 '),('5','5')]),
- form.Radio('Hybrid',
- [('1','1 '),('2','2 '),('3','3 '),('4','4 '),('5','5')]),
- form.Radio('Hybrid+',
- [('1','1 '),('2','2 '),('3','3 '),('4','4 '),('5','5')]),
- form.Dropdown('expertise',
- ["Newbie", "Intermediate", "Advanced", "Guru", "Chuck Norris"],
- description ='Debian expertise'),
- form.Textarea('comments', rows="7", cols="60",
- description="Anything else to share?"),
-
- )
- return send_form
-
-class FeedbackThanks:
- def POST(self):
- return render.feedbackThanks()
+def add_global_hook():
+ g = web.storage({"counter": "1"})
+ def _wrapper(handler):
+ web.ctx.globals = g
+ return handler()
+ return _wrapper
render = web.template.render('templates/', base='layout')
urls = ('/', 'Index',
- '/feedback', 'FeedbackForm',
- '/thanks', 'FeedbackThanks'
+ '/apprec', 'AppRecommender',
+ '/thanks', 'Thanks'
)
web.webapi.internalerror = web.debugerror
if __name__ == "__main__":
- app = web.application(urls, globals())
- app.add_processor(add_global_hook())
- app.run()
+ apprec = web.application(urls, globals())
+ apprec.add_processor(add_global_hook())
+ apprec.run()
diff --git a/src/web/templates/apprec.html b/src/web/templates/apprec.html
new file mode 100644
index 0000000..54cc63e
--- /dev/null
+++ b/src/web/templates/apprec.html
@@ -0,0 +1,48 @@
+$def with (action, method, recommends, form)
+$var title: Feedback
+$var mod = 'feedback';
+
+
+
+
+
+ Recommendations
+
+
+
Results per strategy:
+
+
+
+
+
+
+
+
diff --git a/src/web/templates/error.html b/src/web/templates/error.html
new file mode 100644
index 0000000..37e1e1c
--- /dev/null
+++ b/src/web/templates/error.html
@@ -0,0 +1,23 @@
+$def with (form)
+$var title: Error
+$var mod = 'error';
+
+
+
+ Welcome to AppRecommender
+
+
+
+
+Your request could not be proccessed due to the following error(s):
+
+
+$for v in form.validators:
+ - $v.msg
+
+
+
Go back and try again.
+
If you believe it is a bug, please report to tassia@gmail.com.
+
+
diff --git a/src/web/templates/feedbackForm.html b/src/web/templates/feedbackForm.html
deleted file mode 100644
index 42149b0..0000000
--- a/src/web/templates/feedbackForm.html
+++ /dev/null
@@ -1,50 +0,0 @@
-$def with (action, method, recommends, form)
-$var title: Feedback
-$var mod = 'feedback';
-
-
-
-
-
- Recommendations
-
-
-
Results per strategy:
-
-
-
-
-
-
-
-
diff --git a/src/web/templates/feedbackThanks.html b/src/web/templates/feedbackThanks.html
deleted file mode 100644
index c268c39..0000000
--- a/src/web/templates/feedbackThanks.html
+++ /dev/null
@@ -1,9 +0,0 @@
-$var title: Feedback
-$var mod = 'thanks';
-
-
-
- Thanks!
-
-
-
diff --git a/src/web/templates/index.html b/src/web/templates/index.html
index 466f27e..d6502d2 100644
--- a/src/web/templates/index.html
+++ b/src/web/templates/index.html
@@ -16,9 +16,7 @@ providing platform independent solutions, it should also follow this
principle.
diff --git a/src/web/templates/layout.html b/src/web/templates/layout.html
index a6e1f46..3f9f261 100644
--- a/src/web/templates/layout.html
+++ b/src/web/templates/layout.html
@@ -40,7 +40,7 @@ function loadPackage(packagename)
- Recommender
+ APP_REC
@@ -48,10 +48,13 @@ function loadPackage(packagename)
Skip Quicknav
@@ -69,11 +72,9 @@ $:content