Commit 928cc9054b057b5b14ed07d6cb6020d6236e866d

Authored by Tássia Camões Araújo
1 parent 79e91d8c
Exists in master and in 1 other branch add_vagrant

Survey refactoring.

Showing 2 changed files with 104 additions and 126 deletions   Show diff stats
src/web/survey.py
@@ -8,6 +8,7 @@ import sys @@ -8,6 +8,7 @@ import sys
8 import simplejson as json 8 import simplejson as json
9 import apt 9 import apt
10 import re 10 import re
  11 +import socket
11 12
12 sys.path.insert(0,"../") 13 sys.path.insert(0,"../")
13 14
@@ -15,6 +16,7 @@ import logging @@ -15,6 +16,7 @@ import logging
15 from config import Config 16 from config import Config
16 from recommender import * 17 from recommender import *
17 from user import * 18 from user import *
  19 +from data import DebianPackage
18 20
19 import urllib 21 import urllib
20 22
@@ -77,64 +79,13 @@ class Package: @@ -77,64 +79,13 @@ class Package:
77 subtags = [] 79 subtags = []
78 return debtags 80 return debtags
79 81
80 -class Request:  
81 - def __init__(self,web_input,submissions_dir,user_id=0,pkgs_list=0):  
82 - self.strategy = ""  
83 - if user_id:  
84 - self.user_id = user_id  
85 - self.outputdir = os.path.join(submissions_dir,user_id)  
86 - logging.info("New round for user %s" % self.user_id)  
87 - else:  
88 - self.outputdir = tempfile.mkdtemp(prefix='',dir=submissions_dir)  
89 - self.user_id = self.outputdir.lstrip(submissions_dir)  
90 - logging.info("Request from user %s" % self.user_id)  
91 - logging.debug("Created dir %s" % self.outputdir)  
92 -  
93 - pkgs_list_file = os.path.join(self.outputdir,"packages_list")  
94 - if pkgs_list:  
95 - self.pkgs_list = pkgs_list  
96 - if not os.path.exists(pkgs_list_file):  
97 - with open(pkgs_list_file,"w") as f:  
98 - for pkg in pkgs_list:  
99 - f.write(pkg+"\n")  
100 - else:  
101 - self.pkgs_list = []  
102 - if web_input['pkgs_file'].value:  
103 - f = open(pkgs_list_file, "w")  
104 - lines = web_input['pkgs_file'].file.readlines()  
105 - with open(os.path.join(self.outputdir,"upload"), "w") as upload:  
106 - upload.writelines(lines)  
107 - # popcon submission format  
108 - if lines[0].startswith('POPULARITY-CONTEST'):  
109 - del lines[0]  
110 - del lines[-1]  
111 - package_name_field = 2  
112 - else:  
113 - package_name_field = 0  
114 - for line in lines:  
115 - self.pkgs_list.append(line.split()[package_name_field])  
116 - for pkg in self.pkgs_list:  
117 - f.write(pkg+'\n')  
118 - f.close()  
119 -  
120 - def __str__(self):  
121 - return "Request %s:\n %s" % (self.user_id,str(self.pkgs_list))  
122 -  
123 - def validates(self):  
124 - self.errors = []  
125 - if not self.pkgs_list:  
126 - self.errors.append("No packages list provided.")  
127 - if self.errors:  
128 - return False  
129 - return True  
130 -  
131 class Save: 82 class Save:
132 def POST(self): 83 def POST(self):
133 web_input = web.input() 84 web_input = web.input()
134 logging.info("Saving user evaluation...") 85 logging.info("Saving user evaluation...")
135 logging.info(web_input) 86 logging.info(web_input)
136 user_id = web_input['user_id'].encode('utf8') 87 user_id = web_input['user_id'].encode('utf8')
137 - with open("./submissions/%s/packages_list" % user_id) as packages_list: 88 + with open("./submissions/%s/uploaded_file" % user_id) as packages_list:
138 pkgs_list = [line.strip() for line in packages_list.readlines()] 89 pkgs_list = [line.strip() for line in packages_list.readlines()]
139 strategy = web_input['strategy'] 90 strategy = web_input['strategy']
140 logging.debug("Saving evaluation for user %s, strategy %s and packages..." 91 logging.debug("Saving evaluation for user %s, strategy %s and packages..."
@@ -164,10 +115,48 @@ class Save: @@ -164,10 +115,48 @@ class Save:
164 else: 115 else:
165 return render.survey_index() 116 return render.survey_index()
166 117
  118 +class Request:
  119 + def __init__(self,web_input,submissions_dir):
  120 + self.strategy = ""
  121 + # Check if it is first round
  122 + if web_input.has_key('user_id'):
  123 + self.user_id = web_input['user_id'].encode('utf8')
  124 + self.user_dir = os.path.join(submissions_dir, self.user_id)
  125 + logging.info("New round for user %s" % self.user_id)
  126 + else:
  127 + self.user_dir = tempfile.mkdtemp(prefix='',dir=submissions_dir)
  128 + self.user_id = self.user_dir.split("/")[-1]
  129 + logging.info("Request from user %s" % self.user_id)
  130 + logging.debug("Created dir %s" % self.user_dir)
  131 + uploaded_file = os.path.join(self.user_dir,"uploaded_file")
  132 + if not os.path.exists(uploaded_file):
  133 + if web_input['pkgs_file'].value:
  134 + lines = web_input['pkgs_file'].file.readlines()
  135 + with open(uploaded_file, "w") as uploaded:
  136 + uploaded.writelines(lines)
  137 + with open(uploaded_file) as uploaded:
  138 + if uploaded.readline().startswith('POPULARITY-CONTEST'):
  139 + self.user = PopconSystem(uploaded_file,self.user_id)
  140 + else:
  141 + self.user = PkgsListSystem(uploaded_file,self.user_id)
  142 +
  143 + def __str__(self):
  144 + return "Request %s:\n %s" % (self.user.user_id,
  145 + str(self.user.pkg_profile))
  146 +
  147 + def validates(self):
  148 + self.errors = []
  149 + if not self.user.pkg_profile:
  150 + self.errors.append("No packages list provided.")
  151 + if self.errors:
  152 + return False
  153 + return True
  154 +
167 class Survey: 155 class Survey:
168 def __init__(self): 156 def __init__(self):
169 logging.info("Setting up survey...") 157 logging.info("Setting up survey...")
170 - self.rec = Recommender(Config()) 158 + self.cfg = Config()
  159 + self.rec = Recommender(self.cfg)
171 self.submissions_dir = "./submissions/" 160 self.submissions_dir = "./submissions/"
172 if not os.path.exists(self.submissions_dir): 161 if not os.path.exists(self.submissions_dir):
173 os.makedirs(self.submissions_dir) 162 os.makedirs(self.submissions_dir)
@@ -175,25 +164,12 @@ class Survey: @@ -175,25 +164,12 @@ class Survey:
175 def POST(self): 164 def POST(self):
176 web_input = web.input(pkgs_file={}) 165 web_input = web.input(pkgs_file={})
177 logging.debug("Survey web_input %s" % str(web_input)) 166 logging.debug("Survey web_input %s" % str(web_input))
178 - self.strategies = ["cb","cbd","cbt","col"]  
179 - # If it is not the first strategy round, save the previous evaluation  
180 - if not web_input.has_key('user_id'):  
181 - request = Request(web_input,self.submissions_dir)  
182 - else:  
183 - user_id = web_input['user_id'].encode('utf8')  
184 - with open("./submissions/%s/packages_list" % user_id) as packages_list:  
185 - pkgs_list = [line.strip() for line in packages_list.readlines()]  
186 - request = Request(web_input,self.submissions_dir,user_id,pkgs_list) 167 + self.strategies = ["demo_cb","demo_cbd","demo_cbt","demo_col"]#,"demo_colco"]
  168 + request = Request(web_input,self.submissions_dir)
187 if not request.validates(): 169 if not request.validates():
188 return render.error_survey() 170 return render.error_survey()
189 else: 171 else:
190 - user = User(dict.fromkeys(request.pkgs_list,1),request.user_id)  
191 - program_profile = user.filter_pkg_profile(os.path.join(self.rec.cfg.filters,"program"))  
192 - desktop_profile = user.filter_pkg_profile(os.path.join(self.rec.cfg.filters,"desktop"))  
193 - if (len(desktop_profile)>10 or  
194 - len(desktop_profile)>len(program_profile)/2):  
195 - self.strategies = [strategy_str+"_desktop" for strategy_str  
196 - in self.strategies[:]] 172 + # Check the remaining strategies and select a new one
197 old_strategies = [dirs for root, dirs, files in 173 old_strategies = [dirs for root, dirs, files in
198 os.walk(os.path.join(self.submissions_dir, 174 os.walk(os.path.join(self.submissions_dir,
199 request.user_id))] 175 request.user_id))]
@@ -203,34 +179,45 @@ class Survey: @@ -203,34 +179,45 @@ class Survey:
203 else: 179 else:
204 strategies = self.strategies 180 strategies = self.strategies
205 if not strategies: 181 if not strategies:
206 - return render.thanks(user_id) 182 + return render.thanks(request.user_id)
207 request.strategy = random.choice(strategies) 183 request.strategy = random.choice(strategies)
208 logging.info("Selected \'%s\' from %s" % (request.strategy,strategies)) 184 logging.info("Selected \'%s\' from %s" % (request.strategy,strategies))
  185 + # Get recommendation
209 self.rec.set_strategy(request.strategy) 186 self.rec.set_strategy(request.strategy)
210 - prediction = self.rec.get_recommendation(user,10).get_prediction()  
211 - logging.info("Prediction for user %s" % user.user_id) 187 + prediction = self.rec.get_recommendation(request.user,2).get_prediction()
  188 + logging.info("Prediction for user %s" % request.user_id)
212 logging.info(str(prediction)) 189 logging.info(str(prediction))
213 - output_dir = ("./submissions/%s/%s/" %  
214 - (user.user_id,request.strategy))  
215 - os.makedirs(output_dir)  
216 - with open(os.path.join(output_dir,"prediction"),"w") as prediction_file: 190 + strategy_dir = os.path.join(request.user_dir,request.strategy)
  191 + os.makedirs(strategy_dir)
  192 + with open(os.path.join(strategy_dir,"prediction"),"w") as prediction_file:
217 for pkg,rating in prediction: 193 for pkg,rating in prediction:
218 prediction_file.write("%s %f.2\n" % (pkg,rating)) 194 prediction_file.write("%s %f.2\n" % (pkg,rating))
219 logging.debug("Saved %s/%s prediction to file" % 195 logging.debug("Saved %s/%s prediction to file" %
220 - (user.user_id,request.strategy)) 196 + (request.user_id,request.strategy))
221 recommendation = [result[0] for result in prediction] 197 recommendation = [result[0] for result in prediction]
222 - pkg_summaries = {}  
223 - pkg_details = []  
224 - cache = apt.Cache()  
225 - for pkg in recommendation:  
226 - try:  
227 - logging.debug("Getting details of package %s" % pkg)  
228 - pkg_details.append(Package().get_details_from_dde(pkg))  
229 - pkg_summaries[pkg] = cache[pkg].candidate.summary  
230 - except:  
231 - pkg_summaries[pkg] = ""  
232 - if pkg_details:  
233 - return render.survey(pkg_details, request) 198 +
  199 + # Check connection to DDE
  200 + try:
  201 + s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  202 + s.connect((self.cfg.dde_server,self.cfg.dde_port))
  203 + dde = 1
  204 + s.close()
  205 + except:
  206 + dde =0
  207 + logging.debug("Could not connect to dde")
  208 + # Load packages details
  209 + pkgs_details = []
  210 + for pkg_name in recommendation:
  211 + logging.info("Getting details of package %s" % pkg_name)
  212 + pkg = DebianPackage(pkg_name)
  213 + if dde:
  214 + pkg.load_details_from_dde(self.cfg.dde_server,self.cfg.dde_port)
  215 + else:
  216 + pkg.load_details_from_apt()
  217 + pkgs_details.append(pkg)
  218 + if pkgs_details:
  219 + logging.info("Rendering survey slide...")
  220 + return render.survey(pkgs_details, request)
234 else: 221 else:
235 return render.error_survey() 222 return render.error_survey()
236 223
@@ -241,7 +228,7 @@ def add_global_hook(): @@ -241,7 +228,7 @@ def add_global_hook():
241 return handler() 228 return handler()
242 return _wrapper 229 return _wrapper
243 230
244 -render = web.template.render('templates/', base='layout') 231 +render = web.template.render('templates/', base='layout', globals={'hasattr':hasattr})
245 render_plain = web.template.render('templates/') 232 render_plain = web.template.render('templates/')
246 233
247 urls = ('/', 'Index', 234 urls = ('/', 'Index',
src/web/templates/survey.html
1 -$def with (pkg_details, request) 1 +$def with (pkgs_details, request)
2 $var title: Survey 2 $var title: Survey
3 $var mod = 'survey'; 3 $var mod = 'survey';
4 $var cssfiles: static/coda-slider-2.0/stylesheets/coda-slider-2.0.css static/css/facebox.css static/css/survey.css 4 $var cssfiles: static/coda-slider-2.0/stylesheets/coda-slider-2.0.css static/css/facebox.css static/css/survey.css
@@ -38,7 +38,7 @@ button below. @@ -38,7 +38,7 @@ button below.
38 38
39 <form action="/save" method="post" enctype="multipart/form-data" name="surveyform"> 39 <form action="/save" method="post" enctype="multipart/form-data" name="surveyform">
40 40
41 -<input type="hidden" name="user_id" value=$request.user_id> 41 +<input type="hidden" name="user_id" value=$request.user.user_id>
42 <input type="hidden" name="strategy" value=$request.strategy> 42 <input type="hidden" name="strategy" value=$request.strategy>
43 <div id="controls-form" style="display: none;" class="show-end"><!-- display show in the end form --> 43 <div id="controls-form" style="display: none;" class="show-end"><!-- display show in the end form -->
44 <label for="finish_button" id="tip-finish"> 44 <label for="finish_button" id="tip-finish">
@@ -57,63 +57,54 @@ button below. @@ -57,63 +57,54 @@ button below.
57 57
58 <div class="coda-slider-wrapper hide-end"> 58 <div class="coda-slider-wrapper hide-end">
59 <div class="coda-slider preload" id="coda-slider-1"> 59 <div class="coda-slider preload" id="coda-slider-1">
60 -$for pkg in pkg_details: 60 +$for pkg in pkgs_details:
61 <div class="panel"> 61 <div class="panel">
62 <div class="panel-wrapper"> 62 <div class="panel-wrapper">
63 <div class="screenshot"> 63 <div class="screenshot">
64 <a class="link-thumb" rel="facebox" 64 <a class="link-thumb" rel="facebox"
65 - href="http://screenshots.debian.net/screenshot/$pkg['package']?.jpg"  
66 - title="Click to enlarge screenshot of package $pkg['package']" alt="Click to enlarge screenshot">  
67 - <img height="70px" src="http://screenshots.debian.net/thumbnail/$pkg['package']"  
68 - alt="Screenshot $pkg['package']" /></a> 65 + href="http://screenshots.debian.net/screenshot/$pkg.name?.jpg"
  66 + title="Click to enlarge screenshot of package $pkg.name" alt="Click to enlarge screenshot">
  67 + <img height="70px" src="http://screenshots.debian.net/thumbnail/$pkg.name"
  68 + alt="Screenshot $pkg.name" /></a>
69 </div><!-- screenshot --> 69 </div><!-- screenshot -->
70 - <h1 style="float: right;">($(pkg_details.index(pkg)+1)/10)</h1>  
71 - <h1 id="title_pkg"> $pkg['package'] <br />  
72 - <span>$pkg['description']</span></h1> 70 + <h1 style="float: right;">($(pkgs_details.index(pkg)+1)/10)</h1>
  71 + <h1 id="title_pkg"> $pkg.name <br />
  72 + <span>$pkg.summary</span></h1>
73 <br style="clear: both;" /> 73 <br style="clear: both;" />
74 <div id="panel-controls" class="glass"> 74 <div id="panel-controls" class="glass">
75 <fieldset> 75 <fieldset>
76 <legend>How do you evaluate this<br> recommendation?</legend> 76 <legend>How do you evaluate this<br> recommendation?</legend>
77 <label class="radioButton"> 77 <label class="radioButton">
78 - <input class="radio" type="radio" name="evaluation-$pkg_details.index(pkg)" value="surprising" /> 78 + <input class="radio" type="radio" name="evaluation-$pkgs_details.index(pkg)" value="surprising" />
79 Pleasantly surprising 79 Pleasantly surprising
80 - <!--<div class="tip tip">  
81 - <p>Pleasantly $pkg['package'] FIXME </p>  
82 - </div>-->  
83 </label><br /> 80 </label><br />
84 <label class="radioButton"> 81 <label class="radioButton">
85 - <input class="radio yesb" type="radio" name="evaluation-$pkg_details.index(pkg)" value="good" /> 82 + <input class="radio yesb" type="radio" name="evaluation-$pkgs_details.index(pkg)" value="good" />
86 Useful 83 Useful
87 - <!--<div class="tip tip">  
88 - <p>Good $pkg['package'] FIXME </p>  
89 - </div>-->  
90 </label><br /> 84 </label><br />
91 <label class="radioButton"> 85 <label class="radioButton">
92 - <input class="radio" type="radio" name="evaluation-$pkg_details.index(pkg)" value="poor" /> 86 + <input class="radio" type="radio" name="evaluation-$(pkgs_details.index(pkg))" value="poor" />
93 Poor 87 Poor
94 - <!--<div class="tip tip">  
95 - <p>Poor $pkg['package'] FIXME </p>  
96 - </div>-->  
97 </label> 88 </label>
98 </fieldset> 89 </fieldset>
99 <br style="clear: both;" /> 90 <br style="clear: both;" />
100 </div><!-- #panel-controls --> 91 </div><!-- #panel-controls -->
101 <div class="content-pkg"> 92 <div class="content-pkg">
102 <ul> 93 <ul>
103 - <li><b>Description</b>:  
104 - <br />$:pkg['long_description']</li>  
105 - $if pkg['homepage']:  
106 - <li><b>Homepage</b>: $pkg['homepage']</li>  
107 - $if pkg['task']:  
108 - <li><b>Tasks</b>: $pkg['task']</li>  
109 - <li><b>Section</b>: $pkg['section']</li>  
110 - $if pkg['recommends']:  
111 - <li><b>Recommends</b>: $pkg['recommends']</li>  
112 - $if pkg['suggests']:  
113 - <li><b>Suggests</b>: $pkg['suggests']</li>  
114 - $if pkg['origin']:  
115 - <li><b>Origin</b>: $pkg['origin']</li>  
116 - <li><b>Maintainer</b>: $pkg['maintainer']</li> 94 + $if hasattr(pkg,'description'):
  95 + <li><b>Description</b>: <br />$:pkg.description</li>
  96 + $if hasattr(pkg,'homepage'):
  97 + <li><b>Homepage</b>: $pkg.homepage</li>
  98 + $if hasattr(pkg,'task'):
  99 + <li><b>Tasks</b>: $pkg.task</li>
  100 + $if hasattr(pkg,'section'):
  101 + <li><b>Section</b>: $pkg.section</li>
  102 + $if hasattr(pkg,'recommends'):
  103 + <li><b>Recommends</b>: $pkg.recommends</li>
  104 + $if hasattr(pkg,'suggests'):
  105 + <li><b>Suggests</b>: $pkg.suggests</li>
  106 + $if hasattr(pkg,'maintainer'):
  107 + <li><b>Maintainer</b>: $pkg.maintainer.</li>
117 </ul> 108 </ul>
118 </div><!-- id="content-pkg" --> 109 </div><!-- id="content-pkg" -->
119 </div><!-- .panel-wrapper --> 110 </div><!-- .panel-wrapper -->