Commit ef8c973335b1d69d09c015d5b390a09cf0d7a803
1 parent
0f563900
Exists in
master
and in
1 other branch
Survey running under apache.
Showing
79 changed files
with
97 additions
and
160 deletions
Show diff stats
src/config.py
| @@ -43,7 +43,7 @@ class Config(Singleton): | @@ -43,7 +43,7 @@ class Config(Singleton): | ||
| 43 | self.output = "log" | 43 | self.output = "log" |
| 44 | 44 | ||
| 45 | ## data_source options | 45 | ## data_source options |
| 46 | - self.base_dir = os.path.expanduser("~/.app-recommender/") | 46 | + self.base_dir = os.path.expanduser("/home/tiago/.app-recommender/") |
| 47 | # filters for valid packages | 47 | # filters for valid packages |
| 48 | self.filters_dir = os.path.join(self.base_dir,"filters") | 48 | self.filters_dir = os.path.join(self.base_dir,"filters") |
| 49 | self.pkgs_filter = os.path.join(self.filters_dir,"desktopapps") | 49 | self.pkgs_filter = os.path.join(self.filters_dir,"desktopapps") |
| @@ -64,9 +64,9 @@ class Config(Singleton): | @@ -64,9 +64,9 @@ class Config(Singleton): | ||
| 64 | self.clusters_dir = os.path.join(self.base_dir,"clusters-dir") | 64 | self.clusters_dir = os.path.join(self.base_dir,"clusters-dir") |
| 65 | self.k_medoids = 100 | 65 | self.k_medoids = 100 |
| 66 | # self.dde_url = "http://dde.debian.net/dde/q/udd/packs/all/%s?t=json" | 66 | # self.dde_url = "http://dde.debian.net/dde/q/udd/packs/all/%s?t=json" |
| 67 | - self.dde_url = "http://46.4.235.200:8000/q/udd/packages/all/%s?t=json" | 67 | + self.dde_url = "http://46.4.235.200:8000/q/udd/packages/prio-debian-sid/%s?t=json" |
| 68 | self.dde_server = "46.4.235.200" | 68 | self.dde_server = "46.4.235.200" |
| 69 | - self.dde_port = "8000" | 69 | + self.dde_port = 8000 |
| 70 | 70 | ||
| 71 | ## recomender options | 71 | ## recomender options |
| 72 | self.strategy = "cb" | 72 | self.strategy = "cb" |
src/web/app_recommender.cfg
| @@ -1,38 +0,0 @@ | @@ -1,38 +0,0 @@ | ||
| 1 | -# Config file for AppRecommender | ||
| 2 | - | ||
| 3 | -[general] | ||
| 4 | -# logging level | ||
| 5 | -debug = 1 | ||
| 6 | -verbose = 0 | ||
| 7 | -# output file | ||
| 8 | -output = log/apprec-survey | ||
| 9 | - | ||
| 10 | -[data_sources] | ||
| 11 | -# path to recommender filters | ||
| 12 | -filters = ~/.app-recommender/filters | ||
| 13 | -# path to apt-xapian-index | ||
| 14 | -axi = /root/.app-recommender/axi_program | ||
| 15 | -# DDE url | ||
| 16 | -dde_url = http://46.4.235.200:8000/q/udd/packages/all/%s?t=json | ||
| 17 | -# old, reindex, cluster, recluster | ||
| 18 | -index_mode = old | ||
| 19 | -# path to popcon index | ||
| 20 | -popcon_index = ~/.app-recommender/popcon-index_program | ||
| 21 | -# path to popcon submissions dir | ||
| 22 | -popcon_dir = ~/.app-recommender/popcon-entries/ | ||
| 23 | -# path to valid_pkgs file | ||
| 24 | -pkgs_filter = program | ||
| 25 | -# path to popcon clusters dir | ||
| 26 | -clusters_dir = ~/.app-recommender/clusters_dir_full | ||
| 27 | -# number of medoids for clustering | ||
| 28 | -k_medoids = 100 | ||
| 29 | -# number of popcon submission for indexing | ||
| 30 | -max_popcon = 1000 | ||
| 31 | - | ||
| 32 | -[recommender] | ||
| 33 | -# recommendation strategy | ||
| 34 | -strategy = cb | ||
| 35 | -# search weighting scheme ('trad' or 'bm25') | ||
| 36 | -weight = bm25 | ||
| 37 | -# user profile size | ||
| 38 | -profile_size = 50 |
| @@ -226,9 +226,11 @@ color: #444; | @@ -226,9 +226,11 @@ color: #444; | ||
| 226 | h5 { | 226 | h5 { |
| 227 | font-style: italic; | 227 | font-style: italic; |
| 228 | font-size: 0.75em; | 228 | font-size: 0.75em; |
| 229 | +color: #444; | ||
| 229 | } | 230 | } |
| 230 | pre { | 231 | pre { |
| 231 | margin: 1.5em 0 1.5em 0; | 232 | margin: 1.5em 0 1.5em 0; |
| 233 | +font-size: 1.3em; | ||
| 232 | overflow: auto; | 234 | overflow: auto; |
| 233 | font-family: monospace; | 235 | font-family: monospace; |
| 234 | white-space: pre; | 236 | white-space: pre; |
| @@ -97,7 +97,6 @@ margin-bottom: 10px; | @@ -97,7 +97,6 @@ margin-bottom: 10px; | ||
| 97 | } | 97 | } |
| 98 | 98 | ||
| 99 | .radioButton, | 99 | .radioButton, |
| 100 | -.radioButton:hover, | ||
| 101 | #next-button, | 100 | #next-button, |
| 102 | #restart-button, | 101 | #restart-button, |
| 103 | #continue-button, | 102 | #continue-button, |
| @@ -118,14 +117,6 @@ z-index: 2; | @@ -118,14 +117,6 @@ z-index: 2; | ||
| 118 | cursor: pointer; | 117 | cursor: pointer; |
| 119 | } | 118 | } |
| 120 | 119 | ||
| 121 | -.radioButton:hover { | ||
| 122 | -height: 20px; | ||
| 123 | -box-shadow: 0 0 4px gray; | ||
| 124 | -border: 1px solid #eeeeec; | ||
| 125 | -background: #eeeeec; | ||
| 126 | -color: #000; | ||
| 127 | -} | ||
| 128 | - | ||
| 129 | #continue-button { | 120 | #continue-button { |
| 130 | float: right; | 121 | float: right; |
| 131 | } | 122 | } |
| @@ -144,7 +135,6 @@ vertical-align: middle; | @@ -144,7 +135,6 @@ vertical-align: middle; | ||
| 144 | width: 150px; | 135 | width: 150px; |
| 145 | height: 20px; | 136 | height: 20px; |
| 146 | margin-bottom: 10px; | 137 | margin-bottom: 10px; |
| 147 | -float: left; | ||
| 148 | font-size: 12px; | 138 | font-size: 12px; |
| 149 | font-weight: 600; | 139 | font-weight: 600; |
| 150 | line-height: 14px; | 140 | line-height: 14px; |
| @@ -155,10 +145,10 @@ z-index: 2; | @@ -155,10 +145,10 @@ z-index: 2; | ||
| 155 | cursor: pointer; | 145 | cursor: pointer; |
| 156 | } | 146 | } |
| 157 | 147 | ||
| 158 | -#optionalform, | ||
| 159 | #panel-controls { | 148 | #panel-controls { |
| 160 | position: relative; | 149 | position: relative; |
| 161 | -width: 170px; | 150 | +width: 200px; |
| 151 | +height: 60px; | ||
| 162 | padding: 5px; | 152 | padding: 5px; |
| 163 | margin: 5px; | 153 | margin: 5px; |
| 164 | border-radius: 5px; | 154 | border-radius: 5px; |
| @@ -180,10 +170,10 @@ font-weight: bold; | @@ -180,10 +170,10 @@ font-weight: bold; | ||
| 180 | #next-button { | 170 | #next-button { |
| 181 | text-align: center; | 171 | text-align: center; |
| 182 | position: absolute; | 172 | position: absolute; |
| 183 | -top: 85px; | ||
| 184 | -right: 70px; | ||
| 185 | -width: 80px; | ||
| 186 | -height: 20px; | 173 | +top: 50px; |
| 174 | +right: 68px; | ||
| 175 | +width: 60px; | ||
| 176 | +height: 16px; | ||
| 187 | float: right; | 177 | float: right; |
| 188 | z-index: 3; | 178 | z-index: 3; |
| 189 | } | 179 | } |
No preview for this file type
src/web/survey.py
| @@ -10,7 +10,7 @@ import apt | @@ -10,7 +10,7 @@ import apt | ||
| 10 | import re | 10 | import re |
| 11 | import socket | 11 | import socket |
| 12 | 12 | ||
| 13 | -sys.path.insert(0,"../") | 13 | +sys.path.insert(0,"/var/www/AppRecommender/src/") |
| 14 | 14 | ||
| 15 | import logging | 15 | import logging |
| 16 | from config import Config | 16 | from config import Config |
| @@ -20,6 +20,9 @@ from data import DebianPackage | @@ -20,6 +20,9 @@ from data import DebianPackage | ||
| 20 | 20 | ||
| 21 | import urllib | 21 | import urllib |
| 22 | 22 | ||
| 23 | +# avoid "RuntimeError: maximum recursion depth exceeded" | ||
| 24 | +sys.setrecursionlimit(50000) | ||
| 25 | + | ||
| 23 | class Index: | 26 | class Index: |
| 24 | def GET(self): | 27 | def GET(self): |
| 25 | return render.survey_index() | 28 | return render.survey_index() |
| @@ -32,12 +35,17 @@ class Thanks: | @@ -32,12 +35,17 @@ class Thanks: | ||
| 32 | def POST(self): | 35 | def POST(self): |
| 33 | web_input = web.input() | 36 | web_input = web.input() |
| 34 | user_id = web_input['user_id'].encode('utf8') | 37 | user_id = web_input['user_id'].encode('utf8') |
| 35 | - with open("./submissions/%s/ident" % user_id,'w') as ident: | 38 | + with open("/var/www/AppRecommender/src/web/submissions/%s/ident" % user_id,'w') as ident: |
| 36 | for key in ["name","email","comments"]: | 39 | for key in ["name","email","comments"]: |
| 37 | if web_input.has_key(key): | 40 | if web_input.has_key(key): |
| 38 | ident.write("%s: %s\n" % (key,web_input[key].encode("utf-8"))) | 41 | ident.write("%s: %s\n" % (key,web_input[key].encode("utf-8"))) |
| 39 | return render.thanks_id() | 42 | return render.thanks_id() |
| 40 | 43 | ||
| 44 | +class Fake: | ||
| 45 | + def GET(self): | ||
| 46 | + return render.index() | ||
| 47 | + #return render_plain.fake() | ||
| 48 | + | ||
| 41 | class Package: | 49 | class Package: |
| 42 | def GET(self, pkg): | 50 | def GET(self, pkg): |
| 43 | result = self.get_details_from_dde(pkg) | 51 | result = self.get_details_from_dde(pkg) |
| @@ -49,8 +57,6 @@ class Package: | @@ -49,8 +57,6 @@ class Package: | ||
| 49 | # parse tags | 57 | # parse tags |
| 50 | tags = self._debtags_list_to_dict(json_data['r']['tag']) | 58 | tags = self._debtags_list_to_dict(json_data['r']['tag']) |
| 51 | json_data['r']['tag'] = tags | 59 | json_data['r']['tag'] = tags |
| 52 | - # format long description | ||
| 53 | - json_data['r']['long_description'] = json_data['r']['long_description'].replace(' .\n','').replace('\n','<br />') | ||
| 54 | return json_data['r'] | 60 | return json_data['r'] |
| 55 | 61 | ||
| 56 | def _debtags_list_to_dict(self, debtags_list): | 62 | def _debtags_list_to_dict(self, debtags_list): |
| @@ -85,7 +91,7 @@ class Save: | @@ -85,7 +91,7 @@ class Save: | ||
| 85 | logging.info("Saving user evaluation...") | 91 | logging.info("Saving user evaluation...") |
| 86 | logging.info(web_input) | 92 | logging.info(web_input) |
| 87 | user_id = web_input['user_id'].encode('utf8') | 93 | user_id = web_input['user_id'].encode('utf8') |
| 88 | - with open("./submissions/%s/uploaded_file" % user_id) as packages_list: | 94 | + with open("/var/www/AppRecommender/src/web/submissions/%s/uploaded_file" % user_id) as packages_list: |
| 89 | pkgs_list = [line.strip() for line in packages_list.readlines()] | 95 | pkgs_list = [line.strip() for line in packages_list.readlines()] |
| 90 | strategy = web_input['strategy'] | 96 | strategy = web_input['strategy'] |
| 91 | logging.debug("Saving evaluation for user %s, strategy %s and packages..." | 97 | logging.debug("Saving evaluation for user %s, strategy %s and packages..." |
| @@ -98,7 +104,7 @@ class Save: | @@ -98,7 +104,7 @@ class Save: | ||
| 98 | for key, value in web_input.items(): | 104 | for key, value in web_input.items(): |
| 99 | if key.startswith("evaluation-"): | 105 | if key.startswith("evaluation-"): |
| 100 | evaluations[value.encode('utf8')].append(key.lstrip("evaluation-")) | 106 | evaluations[value.encode('utf8')].append(key.lstrip("evaluation-")) |
| 101 | - output_dir = ("./submissions/%s/%s/" % (user_id,strategy)) | 107 | + output_dir = ("/var/www/AppRecommender/src/web/submissions/%s/%s/" % (user_id,strategy)) |
| 102 | for key,value in evaluations.items(): | 108 | for key,value in evaluations.items(): |
| 103 | with open(os.path.join(output_dir,key),'w') as output: | 109 | with open(os.path.join(output_dir,key),'w') as output: |
| 104 | for item in value: | 110 | for item in value: |
| @@ -157,14 +163,14 @@ class Survey: | @@ -157,14 +163,14 @@ class Survey: | ||
| 157 | logging.info("Setting up survey...") | 163 | logging.info("Setting up survey...") |
| 158 | self.cfg = Config() | 164 | self.cfg = Config() |
| 159 | self.rec = Recommender(self.cfg) | 165 | self.rec = Recommender(self.cfg) |
| 160 | - self.submissions_dir = "./submissions/" | 166 | + self.submissions_dir = "/var/www/AppRecommender/src/web/submissions/" |
| 161 | if not os.path.exists(self.submissions_dir): | 167 | if not os.path.exists(self.submissions_dir): |
| 162 | os.makedirs(self.submissions_dir) | 168 | os.makedirs(self.submissions_dir) |
| 163 | 169 | ||
| 164 | def POST(self): | 170 | def POST(self): |
| 165 | web_input = web.input(pkgs_file={}) | 171 | web_input = web.input(pkgs_file={}) |
| 166 | logging.debug("Survey web_input %s" % str(web_input)) | 172 | logging.debug("Survey web_input %s" % str(web_input)) |
| 167 | - self.strategies = ["demo_cb","demo_cbd","demo_cbt","demo_col"]#,"demo_colco"] | 173 | + self.strategies = ["knn","knn_eset","cbd_eset","knnco"]#,"demo_colco"] |
| 168 | request = Request(web_input,self.submissions_dir) | 174 | request = Request(web_input,self.submissions_dir) |
| 169 | if not request.validates(): | 175 | if not request.validates(): |
| 170 | return render.error_survey() | 176 | return render.error_survey() |
| @@ -184,7 +190,7 @@ class Survey: | @@ -184,7 +190,7 @@ class Survey: | ||
| 184 | logging.info("Selected \'%s\' from %s" % (request.strategy,strategies)) | 190 | logging.info("Selected \'%s\' from %s" % (request.strategy,strategies)) |
| 185 | # Get recommendation | 191 | # Get recommendation |
| 186 | self.rec.set_strategy(request.strategy) | 192 | self.rec.set_strategy(request.strategy) |
| 187 | - prediction = self.rec.get_recommendation(request.user,2).get_prediction() | 193 | + prediction = self.rec.get_recommendation(request.user,10).get_prediction() |
| 188 | logging.info("Prediction for user %s" % request.user_id) | 194 | logging.info("Prediction for user %s" % request.user_id) |
| 189 | logging.info(str(prediction)) | 195 | logging.info(str(prediction)) |
| 190 | strategy_dir = os.path.join(request.user_dir,request.strategy) | 196 | strategy_dir = os.path.join(request.user_dir,request.strategy) |
| @@ -228,23 +234,32 @@ def add_global_hook(): | @@ -228,23 +234,32 @@ def add_global_hook(): | ||
| 228 | return handler() | 234 | return handler() |
| 229 | return _wrapper | 235 | return _wrapper |
| 230 | 236 | ||
| 231 | -render = web.template.render('templates/', base='layout', globals={'hasattr':hasattr}) | ||
| 232 | -render_plain = web.template.render('templates/') | ||
| 233 | - | ||
| 234 | -urls = ('/', 'Index', | ||
| 235 | - '/survey', 'Survey', | ||
| 236 | - '/apprec', 'Survey', | ||
| 237 | - '/thanks', 'Thanks', | ||
| 238 | - '/save', 'Save', | ||
| 239 | - '/thanks', 'Thanks', | ||
| 240 | - '/about', 'About', | ||
| 241 | - '/package/(.*)', 'Package' | 237 | +render = web.template.render('/var/www/AppRecommender/src/web/templates/', base='layout', globals={'hasattr':hasattr}) |
| 238 | +render_plain = web.template.render('/var/www/AppRecommender/src/web/templates/') | ||
| 239 | + | ||
| 240 | +urls = ('/survey', 'Index', | ||
| 241 | + '/survey/', 'Index', | ||
| 242 | + '/survey/survey', 'Survey', | ||
| 243 | + '/survey/apprec', 'Survey', | ||
| 244 | + '/survey/thanks', 'Thanks', | ||
| 245 | + '/survey/save', 'Save', | ||
| 246 | + '/survey/thanks', 'Thanks', | ||
| 247 | + '/survey/about', 'About', | ||
| 248 | + '/survey/package/(.*)', 'Package', | ||
| 249 | + '/', 'Index', | ||
| 250 | + '/index', 'Index' | ||
| 251 | + #'/', 'Fake', | ||
| 252 | + #'/index', 'Fake' | ||
| 242 | ) | 253 | ) |
| 243 | 254 | ||
| 244 | web.webapi.internalerror = web.debugerror | 255 | web.webapi.internalerror = web.debugerror |
| 245 | 256 | ||
| 246 | -if __name__ == "__main__": | ||
| 247 | - cfg = Config() | ||
| 248 | - apprec = web.application(urls, globals()) | ||
| 249 | - apprec.add_processor(add_global_hook()) | ||
| 250 | - apprec.run() | 257 | +#if __name__ == "__main__": |
| 258 | +cfg = Config() | ||
| 259 | +# apprec = web.application(urls, globals()) | ||
| 260 | +# application = web.application(urls, globals()).wsgifunc() | ||
| 261 | +app = web.application(urls, globals(), autoreload=False) | ||
| 262 | +application = app.wsgifunc() | ||
| 263 | + | ||
| 264 | +# apprec.add_processor(add_global_hook()) | ||
| 265 | +# apprec.run() |
| @@ -6,8 +6,8 @@ $var jsfiles: static/js/facebox.js | @@ -6,8 +6,8 @@ $var jsfiles: static/js/facebox.js | ||
| 6 | <script type="text/javascript"> | 6 | <script type="text/javascript"> |
| 7 | $$(document).ready(function() { | 7 | $$(document).ready(function() { |
| 8 | $$('a[rel*=facebox]').facebox({ | 8 | $$('a[rel*=facebox]').facebox({ |
| 9 | - loadingImage : '/static/images/loading.gif', | ||
| 10 | - closeImage : '/static/images/closelabel.png' | 9 | + loadingImage : 'static/images/loading.gif', |
| 10 | + closeImage : 'static/images/closelabel.png' | ||
| 11 | }); | 11 | }); |
| 12 | }); | 12 | }); |
| 13 | </script> | 13 | </script> |
| @@ -30,9 +30,9 @@ initially developed using the Debian Project infrasctructure, but the solution | @@ -30,9 +30,9 @@ initially developed using the Debian Project infrasctructure, but the solution | ||
| 30 | is essentially distro-independent and can even be adapted to non GNU/Linux | 30 | is essentially distro-independent and can even be adapted to non GNU/Linux |
| 31 | systems given that there is available data for that.</p> | 31 | systems given that there is available data for that.</p> |
| 32 | 32 | ||
| 33 | -<a rel="facebox" href="/static/images/diaappr.png" title="AppRecommender Diagram"> | 33 | +<a rel="facebox" href="static/images/diaappr.png" title="AppRecommender Diagram"> |
| 34 | <img style="float: right; margin: 10px;" alt="AppRecommender dataflow" | 34 | <img style="float: right; margin: 10px;" alt="AppRecommender dataflow" |
| 35 | -src="/static/images/diaappr.png" width="230px" /></a> | 35 | +src="static/images/diaappr.png" width="230px" /></a> |
| 36 | <br /> | 36 | <br /> |
| 37 | 37 | ||
| 38 | <p align="justify">The picture on the right gives an idea of the data workflow | 38 | <p align="justify">The picture on the right gives an idea of the data workflow |
| @@ -7,8 +7,8 @@ $var jsfiles: static/js/facebox.js | @@ -7,8 +7,8 @@ $var jsfiles: static/js/facebox.js | ||
| 7 | <script type="application/x-javascript"> | 7 | <script type="application/x-javascript"> |
| 8 | $$(document).ready(function() { | 8 | $$(document).ready(function() { |
| 9 | $$('a[rel*=facebox]').facebox({ | 9 | $$('a[rel*=facebox]').facebox({ |
| 10 | - loadingImage : '/static/images/loading.gif', | ||
| 11 | - closeImage : '/static/images/closelabel.png' | 10 | + loadingImage : 'static/images/loading.gif', |
| 11 | + closeImage : 'static/images/closelabel.png' | ||
| 12 | }); | 12 | }); |
| 13 | 13 | ||
| 14 | $$('.like_button').mouseenter(function(e) { | 14 | $$('.like_button').mouseenter(function(e) { |
| @@ -62,7 +62,7 @@ $$(document).ready(function() { | @@ -62,7 +62,7 @@ $$(document).ready(function() { | ||
| 62 | 62 | ||
| 63 | <h1>Recomendation</h1> | 63 | <h1>Recomendation</h1> |
| 64 | 64 | ||
| 65 | -<form action="/thanks" method="post" enctype="multipart/form-data"> | 65 | +<form action="thanks" method="post" enctype="multipart/form-data"> |
| 66 | 66 | ||
| 67 | <div id="result-thumbnail"> | 67 | <div id="result-thumbnail"> |
| 68 | $for strategy, result in recommends.items(): | 68 | $for strategy, result in recommends.items(): |
| @@ -14,8 +14,8 @@ window.onload = function() { | @@ -14,8 +14,8 @@ window.onload = function() { | ||
| 14 | <script type="application/x-javascript"> | 14 | <script type="application/x-javascript"> |
| 15 | $$(document).ready(function() { | 15 | $$(document).ready(function() { |
| 16 | $$('a[rel*=facebox]').facebox({ | 16 | $$('a[rel*=facebox]').facebox({ |
| 17 | - loadingImage : '/static/images/loading.gif', | ||
| 18 | - closeImage : '/static/images/closelabel.png' | 17 | + loadingImage : 'static/images/loading.gif', |
| 18 | + closeImage : 'static/images/closelabel.png' | ||
| 19 | }); | 19 | }); |
| 20 | $$("#tags-box").click(function () { | 20 | $$("#tags-box").click(function () { |
| 21 | $$("#tags-box").hide(1000); | 21 | $$("#tags-box").hide(1000); |
| @@ -669,14 +669,11 @@ function showtags(tagid) { | @@ -669,14 +669,11 @@ function showtags(tagid) { | ||
| 669 | <div class="textbox"> | 669 | <div class="textbox"> |
| 670 | <h1>You might also like...</h1> | 670 | <h1>You might also like...</h1> |
| 671 | 671 | ||
| 672 | -<p>Provide a list of packages or upload a popcon submission file and you'll get | ||
| 673 | -a list of suggested packages automatically computed by AppRecommender.<!-- You can | ||
| 674 | -customize the recommender setup or let it randomly choose one.--></p> | 672 | +<p>Provide a popcon submission's file and you'll get |
| 673 | +a list of suggested packages automatically computed by AppRecommender. | ||
| 674 | +</p> | ||
| 675 | 675 | ||
| 676 | -<p>Given the recommendation result, please evaluate each application and | ||
| 677 | -choose if you want to continue with another round of suggestions. | ||
| 678 | -<!--fill the form that follows the recommendation results.--> </p><p>Your | ||
| 679 | -feedback is very much appreciated!</p> | 676 | +<p>This is a tentative web interface for the recommender, if you have any suggestion about it, please get in touch.</p> |
| 680 | 677 | ||
| 681 | </div> | 678 | </div> |
| 682 | 679 |
| @@ -8,16 +8,16 @@ $ url_base = "/" | @@ -8,16 +8,16 @@ $ url_base = "/" | ||
| 8 | <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" /> | 8 | <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" /> |
| 9 | <title>AppRecommender - $content.title</title> | 9 | <title>AppRecommender - $content.title</title> |
| 10 | <link rev="made" href="mailto:tassia@gmail.com" /> | 10 | <link rev="made" href="mailto:tassia@gmail.com" /> |
| 11 | - <link rel="shortcut icon" href="static/favicon.ico" /> | 11 | + <link rel="shortcut icon" href="$(url_base)static/favicon.ico" /> |
| 12 | 12 | ||
| 13 | - <link href="static/css/style.css" rel="stylesheet" type="text/css" media="screen" charset="utf-8" /> | 13 | + <link href="$(url_base)static/css/style.css" rel="stylesheet" type="text/css" media="screen" charset="utf-8" /> |
| 14 | 14 | ||
| 15 | $if content.has_key('cssfiles'): | 15 | $if content.has_key('cssfiles'): |
| 16 | $for css in content.cssfiles.split(): | 16 | $for css in content.cssfiles.split(): |
| 17 | - <link href="$css" rel="stylesheet" type="text/css" media="screen" charset="utf-8" /> | 17 | + <link href="$(url_base)$css" rel="stylesheet" type="text/css" media="screen" charset="utf-8" /> |
| 18 | 18 | ||
| 19 | - <script src="/static/js/jquery.js" type="text/javascript"></script> | ||
| 20 | - <script src="/static/js/FormManager.js" type="text/javascript"></script> | 19 | + <script src="$(url_base)static/js/jquery.js" type="text/javascript"></script> |
| 20 | + <script src="$(url_base)static/js/FormManager.js" type="text/javascript"></script> | ||
| 21 | 21 | ||
| 22 | $if content.has_key('jsfiles'): | 22 | $if content.has_key('jsfiles'): |
| 23 | $for js in content.jsfiles.split(): | 23 | $for js in content.jsfiles.split(): |
| @@ -63,7 +63,7 @@ function validateForm() | @@ -63,7 +63,7 @@ function validateForm() | ||
| 63 | <div id="header" class="glass"> | 63 | <div id="header" class="glass"> |
| 64 | <a href="$url_base" title="AppRecommender"><h1 id="logo"><span>AppRecommender</span></h1></a> | 64 | <a href="$url_base" title="AppRecommender"><h1 id="logo"><span>AppRecommender</span></h1></a> |
| 65 | <div id="recommender-box"> | 65 | <div id="recommender-box"> |
| 66 | - <form action="apprec" enctype="multipart/form-data" method="post" name="weboptions" onsubmit="return validateForm()"> | 66 | + <form action="/survey/apprec" enctype="multipart/form-data" method="post" name="weboptions" onsubmit="return validateForm()"> |
| 67 | <fieldset> | 67 | <fieldset> |
| 68 | <div id="submit-box"> | 68 | <div id="submit-box"> |
| 69 | <input type="submit" value="START" id="submit-button" class="glass"><br /> | 69 | <input type="submit" value="START" id="submit-button" class="glass"><br /> |
| @@ -2,11 +2,11 @@ $def with (pkg) | @@ -2,11 +2,11 @@ $def with (pkg) | ||
| 2 | 2 | ||
| 3 | <div class="align-left" id="voting_box"> | 3 | <div class="align-left" id="voting_box"> |
| 4 | <button type="button" class="like_button" onclick=";return false;" id="like" > | 4 | <button type="button" class="like_button" onclick=";return false;" id="like" > |
| 5 | - <img src="/static/images/pixel-vfl73.gif" alt=""> | 5 | + <img src="static/images/pixel-vfl73.gif" alt=""> |
| 6 | </button> | 6 | </button> |
| 7 | | 7 | |
| 8 | <button type="button" class="dislike_button" onclick=";return false;" id="dislike" > | 8 | <button type="button" class="dislike_button" onclick=";return false;" id="dislike" > |
| 9 | - <img src="/static/images/pixel-vfl73.gif" alt=""> | 9 | + <img src="static/images/pixel-vfl73.gif" alt=""> |
| 10 | </button> | 10 | </button> |
| 11 | | 11 | |
| 12 | <div id="update_count" style="float:left;"> | 12 | <div id="update_count" style="float:left;"> |
src/web/templates/survey.html
| @@ -2,7 +2,7 @@ $def with (pkgs_details, request) | @@ -2,7 +2,7 @@ $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 |
| 5 | -$var jsfiles: static/coda-slider-2.0/javascripts/jquery-1.3.2.min.js static/coda-slider-2.0/javascripts/jquery.coda-slider-2.0.js static/coda-slider-2.0/javascripts/jquery.easing.1.3.js static/js/facebox.js | 5 | +$var jsfiles: /static/coda-slider-2.0/javascripts/jquery-1.3.2.min.js /static/coda-slider-2.0/javascripts/jquery.coda-slider-2.0.js /static/coda-slider-2.0/javascripts/jquery.easing.1.3.js /static/js/facebox.js |
| 6 | 6 | ||
| 7 | <script type="text/javascript"> | 7 | <script type="text/javascript"> |
| 8 | $$(document).ready(function() { | 8 | $$(document).ready(function() { |
| @@ -16,14 +16,13 @@ $var jsfiles: static/coda-slider-2.0/javascripts/jquery-1.3.2.min.js static/coda | @@ -16,14 +16,13 @@ $var jsfiles: static/coda-slider-2.0/javascripts/jquery-1.3.2.min.js static/coda | ||
| 16 | }); | 16 | }); |
| 17 | $$('#coda-slider-1').codaSlider({dynamicTabs: false, dynamicArrowLeftText: "L", dynamicArrowRightText:"Next" }); | 17 | $$('#coda-slider-1').codaSlider({dynamicTabs: false, dynamicArrowLeftText: "L", dynamicArrowRightText:"Next" }); |
| 18 | }); | 18 | }); |
| 19 | - | ||
| 20 | </script> | 19 | </script> |
| 21 | 20 | ||
| 22 | 21 | ||
| 23 | <div id="maincontent"> | 22 | <div id="maincontent"> |
| 24 | <div class="innertube"> | 23 | <div class="innertube"> |
| 25 | 24 | ||
| 26 | -<h1>AppRecommender Survey</h1> | 25 | +<h1>AppRecommender survey</h1> |
| 27 | 26 | ||
| 28 | <div class="show-end" style="display: none;"> | 27 | <div class="show-end" style="display: none;"> |
| 29 | 28 | ||
| @@ -35,7 +34,6 @@ button below. | @@ -35,7 +34,6 @@ button below. | ||
| 35 | 34 | ||
| 36 | </div> | 35 | </div> |
| 37 | 36 | ||
| 38 | - | ||
| 39 | <form action="save" method="post" enctype="multipart/form-data" name="surveyform"> | 37 | <form action="save" method="post" enctype="multipart/form-data" name="surveyform"> |
| 40 | 38 | ||
| 41 | <input type="hidden" name="user_id" value=$request.user.user_id> | 39 | <input type="hidden" name="user_id" value=$request.user.user_id> |
| @@ -57,26 +55,14 @@ button below. | @@ -57,26 +55,14 @@ button below. | ||
| 57 | 55 | ||
| 58 | <div class="coda-slider-wrapper hide-end"> | 56 | <div class="coda-slider-wrapper hide-end"> |
| 59 | <div class="coda-slider preload" id="coda-slider-1"> | 57 | <div class="coda-slider preload" id="coda-slider-1"> |
| 58 | + <h5 style="float: right;">How do you evaluate this recommendation?</h5> <br /> | ||
| 60 | $for pkg in pkgs_details: | 59 | $for pkg in pkgs_details: |
| 61 | <div class="panel"> | 60 | <div class="panel"> |
| 62 | - <div class="panel-wrapper"> | ||
| 63 | - <div class="screenshot"> | ||
| 64 | - <a class="link-thumb" rel="facebox" | ||
| 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 --> | ||
| 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;" /> | ||
| 74 | <div id="panel-controls" class="glass"> | 61 | <div id="panel-controls" class="glass"> |
| 75 | <fieldset> | 62 | <fieldset> |
| 76 | - <legend>How do you evaluate this<br> recommendation?</legend> | ||
| 77 | <label class="radioButton"> | 63 | <label class="radioButton"> |
| 78 | <input class="radio" type="radio" name="evaluation-$pkgs_details.index(pkg)" value="surprising" /> | 64 | <input class="radio" type="radio" name="evaluation-$pkgs_details.index(pkg)" value="surprising" /> |
| 79 | - Pleasantly surprising | 65 | + Pleasantly surprising |
| 80 | </label><br /> | 66 | </label><br /> |
| 81 | <label class="radioButton"> | 67 | <label class="radioButton"> |
| 82 | <input class="radio yesb" type="radio" name="evaluation-$pkgs_details.index(pkg)" value="good" /> | 68 | <input class="radio yesb" type="radio" name="evaluation-$pkgs_details.index(pkg)" value="good" /> |
| @@ -89,23 +75,25 @@ $for pkg in pkgs_details: | @@ -89,23 +75,25 @@ $for pkg in pkgs_details: | ||
| 89 | </fieldset> | 75 | </fieldset> |
| 90 | <br style="clear: both;" /> | 76 | <br style="clear: both;" /> |
| 91 | </div><!-- #panel-controls --> | 77 | </div><!-- #panel-controls --> |
| 78 | + <div class="panel-wrapper"> | ||
| 79 | + <div class="screenshot"> | ||
| 80 | + <a class="link-thumb" rel="facebox" | ||
| 81 | + href="http://screenshots.debian.net/screenshot/$pkg.name?.jpg" | ||
| 82 | + title="Click to enlarge screenshot of package $pkg.name" alt="Click to enlarge screenshot"> | ||
| 83 | + <img height="80" src="http://screenshots.debian.net/thumbnail/$pkg.name" | ||
| 84 | + alt="Screenshot $pkg.name" /></a> | ||
| 85 | + </div><!-- screenshot --> | ||
| 86 | + <h1 id="title_pkg"> $pkg.name <span>($(pkgs_details.index(pkg)+1)/10)</span> <br /> | ||
| 87 | + <span>$pkg.summary</span></h1> <br /> | ||
| 92 | <div class="content-pkg"> | 88 | <div class="content-pkg"> |
| 93 | - <ul> | ||
| 94 | $if hasattr(pkg,'description'): | 89 | $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> | 90 | + <pre>$:pkg.description</pre> |
| 91 | + <ul> | ||
| 106 | $if hasattr(pkg,'maintainer'): | 92 | $if hasattr(pkg,'maintainer'): |
| 107 | - <li><b>Maintainer</b>: $pkg.maintainer.</li> | ||
| 108 | - </ul> | 93 | + <li><pre> Maintained by $:pkg.maintainer</pre></li> |
| 94 | + $if hasattr(pkg,'homepage'): | ||
| 95 | + <li><pre> Homepage is $:pkg.homepage</pre></li> | ||
| 96 | + </ul> | ||
| 109 | </div><!-- id="content-pkg" --> | 97 | </div><!-- id="content-pkg" --> |
| 110 | </div><!-- .panel-wrapper --> | 98 | </div><!-- .panel-wrapper --> |
| 111 | </div><!-- .panel --> | 99 | </div><!-- .panel --> |
| @@ -19,31 +19,14 @@ window.onload = function() { | @@ -19,31 +19,14 @@ window.onload = function() { | ||
| 19 | 19 | ||
| 20 | <p>Participate in this survey and contribute for the development of | 20 | <p>Participate in this survey and contribute for the development of |
| 21 | <a href="http://github.com/tassia/AppRecommender">AppRecommender</a>, | 21 | <a href="http://github.com/tassia/AppRecommender">AppRecommender</a>, |
| 22 | -a recommender system for GNU/Linux applications.</p> | ||
| 23 | -<table> | ||
| 24 | -<tr> | ||
| 25 | - <td><h3>1.</h3></td> | ||
| 26 | - <td><p align="justify"> Provide a list of packages installed in a real | 22 | +a recommender system for GNU/Linux applications.</p><br /> |
| 23 | + <p align="justify"> Provide a list of packages installed in a real | ||
| 27 | running system and a set of applications will be suggested for it. You can | 24 | running system and a set of applications will be suggested for it. You can |
| 28 | upload a popularity-contest submission file (usually located at | 25 | upload a popularity-contest submission file (usually located at |
| 29 | '/var/log/popularity-contest') or any other file with packages name as first | 26 | '/var/log/popularity-contest') or any other file with packages name as first |
| 30 | field of each line. For instance, you can run the following command and | 27 | field of each line. For instance, you can run the following command and |
| 31 | - upload the generated 'packages.list' file.</p> | ||
| 32 | - <p><code> # dpkg-query --show > packages.list </code></p></td> | ||
| 33 | -</tr> | ||
| 34 | -<tr> | ||
| 35 | - <td><h3>2.</h3></td> | ||
| 36 | - <td><p align="justify">Given a list of 10 suggested applications you will be | ||
| 37 | - asked to evaluate each recommendation. Upon completion of one round of | ||
| 38 | - evaluations, if you choose to continue another suggestion will be generated | ||
| 39 | - using a different recommender strategy. Alternativelly, you can conclude your | ||
| 40 | - participation.</p></td> | ||
| 41 | -</tr> | ||
| 42 | -<tr> | ||
| 43 | - <td><h3>3.</h3></td> | ||
| 44 | - <td><p align="justify">Identification and comments are facultative.</p></td> | ||
| 45 | -</tr> | ||
| 46 | -<table> | 28 | + upload the generated 'packages.list' file.</p><br /> |
| 29 | + <p><code> # dpkg-query --show > packages.list </code></p> | ||
| 47 | </div> | 30 | </div> |
| 48 | 31 | ||
| 49 | </div><!-- class="innertube" --> | 32 | </div><!-- class="innertube" --> |
| @@ -26,7 +26,7 @@ appreciated!</p><br /> | @@ -26,7 +26,7 @@ appreciated!</p><br /> | ||
| 26 | </p><br /> | 26 | </p><br /> |
| 27 | </center> | 27 | </center> |
| 28 | 28 | ||
| 29 | - <form action="/thanks" method="post" enctype="multipart/form-data" name="identification_form"> | 29 | + <form action="thanks" method="post" enctype="multipart/form-data" name="identification_form"> |
| 30 | <label> | 30 | <label> |
| 31 | <input type="hidden" name="user_id" value=$user_id> | 31 | <input type="hidden" name="user_id" value=$user_id> |
| 32 | Name: <input class="text" type="text" name="name" value="" size="40"> | 32 | Name: <input class="text" type="text" name="name" value="" size="40"> |