From 360e3a7b26927c1e759de1bba8f08400e9c18a92 Mon Sep 17 00:00:00 2001 From: FreakJoe Date: Fri, 10 Mar 2017 19:46:01 +0100 Subject: [PATCH 1/8] Setting fee via web interface --- rein/cli.py | 35 +++++++++++++++++++++++++++++------ rein/html/css/style_v2.css | 3 +++ rein/html/js/settings.js | 17 +++++++++++++++++ rein/html/settings.html | 23 +++++++++++++++++++---- 4 files changed, 68 insertions(+), 10 deletions(-) create mode 100644 rein/html/js/settings.js diff --git a/rein/cli.py b/rein/cli.py index c37c970..2b921af 100644 --- a/rein/cli.py +++ b/rein/cli.py @@ -1202,11 +1202,7 @@ def status(multi, identity, jobid): else: click.echo("Job id not found") - -@cli.command() -@click.argument('key', required=True) -@click.argument('value', required=True) -def config(key, value): +def config_common(key, value): """ Set configuration variable. Parses true/false, on/off, and passes anything else unaltered to the db. @@ -1223,6 +1219,17 @@ def config(key, value): else: PersistConfig.set(rein, key, value) +@cli.command() +@click.argument('key', required=True) +@click.argument('value', required=True) +def config(key, value): + """ + Set configuration variable. Parses true/false, on/off, and passes + anything else unaltered to the db. + """ + + config_common(key, value) + # leave specific config commands in for backwards compatibility, remove in 0.4 @cli.command() @@ -1576,6 +1583,20 @@ def unhide(): except: return 'false' + @app.route('/config', methods=['POST']) + def config_web(): + """Allows for changes to the user's config via the web interface""" + + try: + key = request.json['key'] + value = request.json['value'] + config_common(key, value) + + except: + return 'false' + + return 'true' + @app.route('/settings', methods=['GET']) def settings(): """Allows for local customization of the web app.""" @@ -1592,7 +1613,9 @@ def settings(): for hidden_mediator in hidden_mediators: hidden_mediator['unhide_button'] = HiddenContent.unhide_button('mediator', hidden_mediator['content_identifier']) - return render_template('settings.html', user=user, hidden_jobs=hidden_jobs, hidden_bids=hidden_bids, hidden_mediators=hidden_mediators) + fee = float(PersistConfig.get(rein, 'fee', 0.001)) + + return render_template('settings.html', user=user, hidden_jobs=hidden_jobs, hidden_bids=hidden_bids, hidden_mediators=hidden_mediators, fee=fee) @app.route("/post", methods=['POST', 'GET']) def job_post(): diff --git a/rein/html/css/style_v2.css b/rein/html/css/style_v2.css index 1709ef2..5e6f42c 100644 --- a/rein/html/css/style_v2.css +++ b/rein/html/css/style_v2.css @@ -2154,6 +2154,9 @@ border-radius: 50%;} } .thumbnail {margin-bottom:0;} .control-group {margin-bottom:30px;} +hr { + border-top: 1px solid #000; +} @media (min-width: 768px) { #sidebar-left.col-sm-2 { opacity: 1; diff --git a/rein/html/js/settings.js b/rein/html/js/settings.js new file mode 100644 index 0000000..14acf36 --- /dev/null +++ b/rein/html/js/settings.js @@ -0,0 +1,17 @@ +function setFee() { + fee = $('#feeInput').val(); + $.ajax({ + method: "POST", + url: "/config", + contentType: "application/json", + data: JSON.stringify({ + 'key': 'fee', + 'value': fee + }), + success: function(data) { + if (data != 'true') { + alert('Your desired fee could not be saved.') + } + } + }) +} \ No newline at end of file diff --git a/rein/html/settings.html b/rein/html/settings.html index c2027b9..a4e047d 100644 --- a/rein/html/settings.html +++ b/rein/html/settings.html @@ -2,14 +2,18 @@ {% from "_form_helpers.html" import render_error %} {% block body %} + +

Settings

-

Hidden content

+
+ +

Hidden content

This section lets you view and unhide hidden content.

-
Jobs
+

Jobs

{% if hidden_jobs %} @@ -31,7 +35,7 @@
Jobs

No jobs have been hidden.

{% endif %} -
Bids
+

Bids

{% if hidden_bids %}
@@ -53,7 +57,7 @@
Bids

No bids have been hidden.

{% endif %} -
Mediators
+

Mediators

{% if hidden_mediators %}
@@ -74,6 +78,17 @@
Mediators
{% else %}

No mediators have been hidden.

{% endif %} + +
+ +

Transaction fee

+

This section lets you adjust the fee that is used for transactions from escrows to mediators and workers.

+ + + + + + {% endblock %} From 48327a79f5789b7f33033f5048f448b046b3f690 Mon Sep 17 00:00:00 2001 From: FreakJoe Date: Sat, 11 Mar 2017 15:06:17 +0100 Subject: [PATCH 2/8] Fixed fee validation --- rein/html/settings.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rein/html/settings.html b/rein/html/settings.html index a4e047d..0e24672 100644 --- a/rein/html/settings.html +++ b/rein/html/settings.html @@ -84,9 +84,9 @@

Mediators

Transaction fee

This section lets you adjust the fee that is used for transactions from escrows to mediators and workers.

-
+ - + From 4a32fad0f347b5af55508eacc3698ae5e263a2ed Mon Sep 17 00:00:00 2001 From: FreakJoe Date: Sat, 11 Mar 2017 15:35:01 +0100 Subject: [PATCH 3/8] Save trust score setting --- rein/cli.py | 2 +- rein/html/js/settings.js | 28 +++++++++++++++++++++++++--- rein/html/settings.html | 26 +++++++++++++++++++++++--- 3 files changed, 49 insertions(+), 7 deletions(-) diff --git a/rein/cli.py b/rein/cli.py index 2b921af..4fc613c 100644 --- a/rein/cli.py +++ b/rein/cli.py @@ -1207,7 +1207,7 @@ def config_common(key, value): Set configuration variable. Parses true/false, on/off, and passes anything else unaltered to the db. """ - keys = ['testnet', 'tor', 'debug', 'fee'] + keys = ['testnet', 'tor', 'debug', 'fee', 'trust_score'] if key not in keys: click.echo("Invalid config setting. Try one of " + ', '.join(keys)) return diff --git a/rein/html/js/settings.js b/rein/html/js/settings.js index 14acf36..4a8903e 100644 --- a/rein/html/js/settings.js +++ b/rein/html/js/settings.js @@ -1,3 +1,11 @@ +function postError(data) { + if (data != 'true') { + alert('Your desired setting could not be saved.') + } else { + alert('Setting saved successfully!') + } +} + function setFee() { fee = $('#feeInput').val(); $.ajax({ @@ -9,9 +17,23 @@ function setFee() { 'value': fee }), success: function(data) { - if (data != 'true') { - alert('Your desired fee could not be saved.') - } + postError(data); + } + }) +} + +function setTrustScore() { + trustScoreEnabled = $('#trustScore').is(':checked'); + $.ajax({ + method: "POST", + url: "/config", + contentType: "application/json", + data: JSON.stringify({ + 'key': 'trust_score', + 'value': trustScoreEnabled.toString() + }), + success: function(data) { + postError(data); } }) } \ No newline at end of file diff --git a/rein/html/settings.html b/rein/html/settings.html index 0e24672..266e712 100644 --- a/rein/html/settings.html +++ b/rein/html/settings.html @@ -84,9 +84,29 @@

Mediators

Transaction fee

This section lets you adjust the fee that is used for transactions from escrows to mediators and workers.

-
- - + +
+ + +
+
+ +
+ + +
+ +

Trust score

+

Would you like to automatically trust scores for users on their ratings page? If so, check the box below. This may make ratings pages slower to load.

+ +
+
+ + +
+
+ +
From e46ccfd1a39f1629c9e59d6d435b72cb2c55ad31 Mon Sep 17 00:00:00 2001 From: FreakJoe Date: Sat, 11 Mar 2017 18:23:25 +0100 Subject: [PATCH 4/8] Opt-in or opt-out option for trust score calculation --- rein/cli.py | 6 ++++-- rein/html/js/trustScore.js | 8 ++++++++ rein/html/ratings.html | 16 +++++++++++++++- rein/html/settings.html | 11 +++++++++-- 4 files changed, 36 insertions(+), 5 deletions(-) create mode 100644 rein/html/js/trustScore.js diff --git a/rein/cli.py b/rein/cli.py index 4fc613c..2876914 100644 --- a/rein/cli.py +++ b/rein/cli.py @@ -1544,8 +1544,9 @@ def rate_web(): @app.route('/ratings/', methods=['GET']) def view_ratings(msin): + display_trust_score = PersistConfig.get(rein, 'trust_score', False) ratings = get_all_user_ratings(log, url, user, rein, msin) - return render_template("ratings.html", user=user, user_rated=get_user_name(log, url, user, rein, msin), msin=msin, ratings=ratings) + return render_template("ratings.html", user=user, user_rated=get_user_name(log, url, user, rein, msin), msin=msin, ratings=ratings, display_trust_score=display_trust_score) @app.route('/hide', methods=['POST']) def hide(): @@ -1614,8 +1615,9 @@ def settings(): hidden_mediator['unhide_button'] = HiddenContent.unhide_button('mediator', hidden_mediator['content_identifier']) fee = float(PersistConfig.get(rein, 'fee', 0.001)) + trust_score = PersistConfig.get(rein, 'trust_score', False) - return render_template('settings.html', user=user, hidden_jobs=hidden_jobs, hidden_bids=hidden_bids, hidden_mediators=hidden_mediators, fee=fee) + return render_template('settings.html', user=user, hidden_jobs=hidden_jobs, hidden_bids=hidden_bids, hidden_mediators=hidden_mediators, fee=fee, trust_score=trust_score) @app.route("/post", methods=['POST', 'GET']) def job_post(): diff --git a/rein/html/js/trustScore.js b/rein/html/js/trustScore.js new file mode 100644 index 0000000..f6c2f5e --- /dev/null +++ b/rein/html/js/trustScore.js @@ -0,0 +1,8 @@ +function setTrustScore(msin, displayId) { + trustScore = getTrustScore(msin); + $('#' + displayId).html(trustScore); +} + +function getTrustScore(msin) { + return msin; +} \ No newline at end of file diff --git a/rein/html/ratings.html b/rein/html/ratings.html index 46b968b..fd3807b 100644 --- a/rein/html/ratings.html +++ b/rein/html/ratings.html @@ -2,9 +2,23 @@ {% from "_form_helpers.html" import render_error %} {% block body %} + +
- This page displays ratings received by {{ user_rated }} (msin: {{ msin }}). +

This page displays ratings received by {{ user_rated }} (msin: {{ msin }}).

+

+ + {% if display_trust_score %} + + {% else %} +

+ {% endif %} +

diff --git a/rein/html/settings.html b/rein/html/settings.html index 266e712..70fbe03 100644 --- a/rein/html/settings.html +++ b/rein/html/settings.html @@ -2,7 +2,7 @@ {% from "_form_helpers.html" import render_error %} {% block body %} - +
@@ -101,7 +101,14 @@

Trust score

- + + {% if trust_score %} + + {% endif %}
From 7df4869b614682c8462fbc704228f0142cd628f4 Mon Sep 17 00:00:00 2001 From: FreakJoe Date: Sat, 11 Mar 2017 19:31:08 +0100 Subject: [PATCH 5/8] Trust score calculation and display --- rein/cli.py | 45 ++++++++++++++++++++++++++++++++++++++ rein/html/js/trustScore.js | 16 +++++++++++++- 2 files changed, 60 insertions(+), 1 deletion(-) diff --git a/rein/cli.py b/rein/cli.py index 2876914..478cb9b 100644 --- a/rein/cli.py +++ b/rein/cli.py @@ -1598,6 +1598,51 @@ def config_web(): return 'true' + @app.route('/trust_score/', defaults={'source_msin': user.msin}) + @app.route('/trust_score//', methods=['GET']) + def trust_score(dest_msin, source_msin): + """Calculates the trust score for a user as identified by his msin. + Algorithm based on the level 2 trust system implemented by Bitcoin OTC + and outlined at https://wiki.bitcoin-otc.com/wiki/OTC_Rating_System#Notes_about_gettrust.""" + + # Grab all ratings commited by source_msin (the client) + ratings_by_source = rein.session.query(Document).filter(and_( + Document.doc_type == 'rating', + Document.contents.like('%\nRater msin: {}%'.format(source_msin)) + )).all() + + # Compile list of users (by msin) that have been rated by source and their ratings + rated_by_source = [] + for rating in ratings_by_source: + rating_dict = document_to_dict(rating.contents) + msin_rated = rating_dict['User msin'] + rating_value = int(rating_dict['Rating']) + if not msin_rated in rated_by_source: + rated_by_source.append((msin_rated, rating_value)) + + # Determine if any of the users rated by source or source have rated dest + # Add source to the list of users source has vouched for with full trust + vouched_users = rated_by_source + [(source_msin, 5)] + # Calculate trust links between source and dest + trust_links = [] + for vouched_user in vouched_users: + (vouched_user_msin, vouched_user_trust) = vouched_user + dest_ratings_by_vouched_user = rein.session.query(Document).filter( + and_( + Document.doc_type == 'rating', + Document.contents.like('%\nRater msin: {}%'.format(vouched_user_msin)), + Document.contents.like('%\nUser msin: {}%'.format(dest_msin)) + )).all() + for rating in dest_ratings_by_vouched_user: + trust_values = [ + vouched_user_trust, + int(document_to_dict(rating.contents)['Rating']) + ] + trust_links.append(min(trust_values)) + + dest_trust_score = json.dumps({'sum': sum(trust_links), 'links': len(trust_links)}) + return dest_trust_score + @app.route('/settings', methods=['GET']) def settings(): """Allows for local customization of the web app.""" diff --git a/rein/html/js/trustScore.js b/rein/html/js/trustScore.js index f6c2f5e..dce4b08 100644 --- a/rein/html/js/trustScore.js +++ b/rein/html/js/trustScore.js @@ -4,5 +4,19 @@ function setTrustScore(msin, displayId) { } function getTrustScore(msin) { - return msin; + result = 'Trust score could not be calculated'; + $.ajax({ + method: "GET", + url: "/trust_score/" + msin, + contentType: "application/json", + async: false, + success: function(data) { + data = JSON.parse(data); + result = 'No trust links between you and the user were found. A trust score could not be calculated.' + if (data['links'] != 0) { + result = 'Trust score: ' + data['sum'] + ', Trust links: ' + data['links']; + } + } + }) + return result; } \ No newline at end of file From 9d6802607df9176b32e0b3646fa902207a00e31a Mon Sep 17 00:00:00 2001 From: FreakJoe Date: Sat, 11 Mar 2017 20:22:34 +0100 Subject: [PATCH 6/8] Documentation and display of average trust score --- doc/ratings-and-trust.md | 17 +++++++++++++++++ rein/cli.py | 2 +- rein/html/js/trustScore.js | 2 +- 3 files changed, 19 insertions(+), 2 deletions(-) create mode 100644 doc/ratings-and-trust.md diff --git a/doc/ratings-and-trust.md b/doc/ratings-and-trust.md new file mode 100644 index 0000000..a17a309 --- /dev/null +++ b/doc/ratings-and-trust.md @@ -0,0 +1,17 @@ +# Ratings and trust + +Rein has two systems in place to help users decide with whom to work with and who to avoid. + +## Ratings + +The first and more simple of the two systems is a five-star rating system. After a job is completed, either through acceptance of the delivery by the client or through successful mediation, all involved users (client, mediator and worker) are given the option to rate the other two participants on a scale from 0 to 5. If a user so desires, he can also leave a comment regarding the other person's performance. + +Across the application, these simple five star ratings are used as an indicator of performance by averaging all ratings a user has received and providing the total number of ratings for reference. A user's ratings, comments on his performance and who he has been rated by can be viewed in more detail on their ratings page. + +## Trust score + +A slightly more sophisticated system allows the user to calculate trust scores for other users on their ratings page. This can be done either automatically, if the user has enabled the setting on his settings page, or manually by clicking a button on an individual ratings page. + +The trust score system is based on the idea that you usually don't trust someone you have no connection to. How would you know that their ratings aren't fake? Usually, you seek out clients, workers or mediators based on someone you do know vouching for them. + +If you're interested in the details, check out https://wiki.bitcoin-otc.com/wiki/OTC_Rating_System#Notes_about_gettrust as Rein's implementation is based on that very idea. \ No newline at end of file diff --git a/rein/cli.py b/rein/cli.py index 478cb9b..2f40fc2 100644 --- a/rein/cli.py +++ b/rein/cli.py @@ -1640,7 +1640,7 @@ def trust_score(dest_msin, source_msin): ] trust_links.append(min(trust_values)) - dest_trust_score = json.dumps({'sum': sum(trust_links), 'links': len(trust_links)}) + dest_trust_score = json.dumps({'score': float(sum(trust_links)) / float(len(trust_links)), 'links': len(trust_links)}) return dest_trust_score @app.route('/settings', methods=['GET']) diff --git a/rein/html/js/trustScore.js b/rein/html/js/trustScore.js index dce4b08..189c2e5 100644 --- a/rein/html/js/trustScore.js +++ b/rein/html/js/trustScore.js @@ -14,7 +14,7 @@ function getTrustScore(msin) { data = JSON.parse(data); result = 'No trust links between you and the user were found. A trust score could not be calculated.' if (data['links'] != 0) { - result = 'Trust score: ' + data['sum'] + ', Trust links: ' + data['links']; + result = 'Trust score: ' + data['score'] + ', Trust links: ' + data['links']; } } }) From 9388dfa17d61fb71584d821c0c6b852e297bbb5d Mon Sep 17 00:00:00 2001 From: FreakJoe Date: Mon, 13 Mar 2017 17:31:02 +0100 Subject: [PATCH 7/8] Added test for trust score calculation --- rein/cli.py | 44 +-------------------- rein/html/settings.html | 2 +- rein/lib/rating.py | 72 +++++++++++++++++++++++++++++++++++ tests/lib/test_trust_score.py | 67 ++++++++++++++++++++++++++++++++ 4 files changed, 142 insertions(+), 43 deletions(-) create mode 100644 tests/lib/test_trust_score.py diff --git a/rein/cli.py b/rein/cli.py index 2f40fc2..0411411 100644 --- a/rein/cli.py +++ b/rein/cli.py @@ -28,7 +28,7 @@ from .lib.script import build_2_of_3, build_mandatory_multisig, check_redeem_scripts from .lib.localization import init_localization from .lib.transaction import partial_spend_p2sh, spend_p2sh, spend_p2sh_mediator, partial_spend_p2sh_mediator, partial_spend_p2sh_mediator_2 -from .lib.rating import add_rating, get_user_jobs, get_average_user_rating, get_average_user_rating_display, get_all_user_ratings +from .lib.rating import add_rating, get_user_jobs, get_average_user_rating, get_average_user_rating_display, get_all_user_ratings, calculate_trust_score # Import config import rein.lib.config as config @@ -1601,47 +1601,7 @@ def config_web(): @app.route('/trust_score/', defaults={'source_msin': user.msin}) @app.route('/trust_score//', methods=['GET']) def trust_score(dest_msin, source_msin): - """Calculates the trust score for a user as identified by his msin. - Algorithm based on the level 2 trust system implemented by Bitcoin OTC - and outlined at https://wiki.bitcoin-otc.com/wiki/OTC_Rating_System#Notes_about_gettrust.""" - - # Grab all ratings commited by source_msin (the client) - ratings_by_source = rein.session.query(Document).filter(and_( - Document.doc_type == 'rating', - Document.contents.like('%\nRater msin: {}%'.format(source_msin)) - )).all() - - # Compile list of users (by msin) that have been rated by source and their ratings - rated_by_source = [] - for rating in ratings_by_source: - rating_dict = document_to_dict(rating.contents) - msin_rated = rating_dict['User msin'] - rating_value = int(rating_dict['Rating']) - if not msin_rated in rated_by_source: - rated_by_source.append((msin_rated, rating_value)) - - # Determine if any of the users rated by source or source have rated dest - # Add source to the list of users source has vouched for with full trust - vouched_users = rated_by_source + [(source_msin, 5)] - # Calculate trust links between source and dest - trust_links = [] - for vouched_user in vouched_users: - (vouched_user_msin, vouched_user_trust) = vouched_user - dest_ratings_by_vouched_user = rein.session.query(Document).filter( - and_( - Document.doc_type == 'rating', - Document.contents.like('%\nRater msin: {}%'.format(vouched_user_msin)), - Document.contents.like('%\nUser msin: {}%'.format(dest_msin)) - )).all() - for rating in dest_ratings_by_vouched_user: - trust_values = [ - vouched_user_trust, - int(document_to_dict(rating.contents)['Rating']) - ] - trust_links.append(min(trust_values)) - - dest_trust_score = json.dumps({'score': float(sum(trust_links)) / float(len(trust_links)), 'links': len(trust_links)}) - return dest_trust_score + return calculate_trust_score(dest_msin, source_msin, rein) @app.route('/settings', methods=['GET']) def settings(): diff --git a/rein/html/settings.html b/rein/html/settings.html index 70fbe03..b106199 100644 --- a/rein/html/settings.html +++ b/rein/html/settings.html @@ -97,7 +97,7 @@

Transaction fee


Trust score

-

Would you like to automatically trust scores for users on their ratings page? If so, check the box below. This may make ratings pages slower to load.

+

Would you like to automatically display trust scores for users on their ratings page? If so, check the box below. This may make ratings pages slower to load.

diff --git a/rein/lib/rating.py b/rein/lib/rating.py index bbd783d..d39dd3b 100644 --- a/rein/lib/rating.py +++ b/rein/lib/rating.py @@ -178,3 +178,75 @@ def get_all_user_ratings(log, url, user, rein, msin): ) return ratings + +def calculate_trust_score(dest_msin=None, source_msin=None, rein=None, test=False, test_ratings=[]): + """Calculates the trust score for a user as identified by his msin. + Algorithm based on the level 2 trust system implemented by Bitcoin OTC + and outlined at https://wiki.bitcoin-otc.com/wiki/OTC_Rating_System#Notes_about_gettrust.""" + + # Grab all ratings commited by source_msin (the client) + ratings_by_source = None + if not test: + ratings_by_source = rein.session.query(Document).filter(and_( + Document.doc_type == 'rating', + Document.contents.like('%\nRater msin: {}%'.format(source_msin)) + )).all() + + else: + ratings_by_source = [test_rating for test_rating in test_ratings if test_rating['Rater msin'] == 'SourceMsin'] + + # Compile list of users (by msin) that have been rated by source and their ratings + rated_by_source = [] + for rating in ratings_by_source: + rating_dict = None + if not test: + rating_dict = document_to_dict(rating.contents) + + else: + rating_dict = rating + + msin_rated = rating_dict['User msin'] + rating_value = int(rating_dict['Rating']) + if not msin_rated in rated_by_source: + rated_by_source.append((msin_rated, rating_value)) + + # Determine if any of the users rated by source or source have rated dest + # Add source to the list of users source has vouched for with full trust + vouched_users = rated_by_source + [(source_msin, 5)] + # Calculate trust links between source and dest + trust_links = [] + for vouched_user in vouched_users: + (vouched_user_msin, vouched_user_trust) = vouched_user + dest_ratings_by_vouched_user = None + if not test: + dest_ratings_by_vouched_user = rein.session.query(Document).filter( + and_( + Document.doc_type == 'rating', + Document.contents.like('%\nRater msin: {}%'.format(vouched_user_msin)), + Document.contents.like('%\nUser msin: {}%'.format(dest_msin)) + )).all() + else: + dest_ratings_by_vouched_user = [test_rating for test_rating in test_ratings if test_rating['Rater msin'] == vouched_user_msin and test_rating['User msin'] == 'DestMsin'] + + for rating in dest_ratings_by_vouched_user: + link_rating = None + if not test: + link_rating = document_to_dict(rating.contents) + + else: + link_rating = rating + + trust_values = [ + vouched_user_trust, + int(link_rating['Rating']) + ] + trust_links.append(min(trust_values)) + + dest_trust_score = { + 'score': float(sum(trust_links)) / float(len(trust_links)), + 'links': len(trust_links) + } + if not test: + dest_trust_score = json.dumps(dest_trust_score) + + return dest_trust_score diff --git a/tests/lib/test_trust_score.py b/tests/lib/test_trust_score.py new file mode 100644 index 0000000..29168b9 --- /dev/null +++ b/tests/lib/test_trust_score.py @@ -0,0 +1,67 @@ +import unittest + +from rein.lib.rating import calculate_trust_score + +# Test cases have to follow certain conventions +# List of dicts / lists of dicts +# Each dict represents a rating, containing the keys +# Rater msin, User msin, Rating +# There must be ratings listing SourceMsin as rater +# The people rated by SourceMsin must have rated (or not rated) DestMsin +############################################### +# Test case 1 flow chart +# 5/5 4/5 +#Link One <------------+ Source +-------------> Link Three +# + + + +# | |3/5 | +# | v | +# | Link Two | +# | + | +# | | | +# | |5/5 | +# | | | +# | v | +# | | +# +---------------------> Dest <-------------------------+ +# 5/5 5/5 + +test_case_1 = [ + { + 'Rater msin': 'SourceMsin', + 'User msin': 'LinkOneMsin', + 'Rating': 5 + }, + { + 'Rater msin': 'SourceMsin', + 'User msin': 'LinkTwoMsin', + 'Rating': 3 + }, + { + 'Rater msin': 'SourceMsin', + 'User msin': 'LinkThreeMsin', + 'Rating': 4 + }, + { + 'Rater msin': 'LinkOneMsin', + 'User msin': 'DestMsin', + 'Rating': 5 + }, + { + 'Rater msin': 'LinkTwoMsin', + 'User msin': 'DestMsin', + 'Rating': 5 + }, + { + 'Rater msin': 'LinkThreeMsin', + 'User msin': 'DestMsin', + 'Rating': 5 + } +] + +class TestTrustScore(unittest.TestCase): + def test_trust_score(self): + """Tests trust score calculation""" + + trust_score_1 = calculate_trust_score(test=True, test_ratings=test_case_1) + self.assertEqual(trust_score_1['score'], 4) + self.assertEqual(trust_score_1['links'], 3) From 9db308cf9731325eda2fce056ddd62a7da8fc416 Mon Sep 17 00:00:00 2001 From: FreakJoe Date: Mon, 13 Mar 2017 17:35:07 +0100 Subject: [PATCH 8/8] Disabled 0-star ratings --- rein/html/js/rate.js | 1 + rein/lib/forms.py | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/rein/html/js/rate.js b/rein/html/js/rate.js index 9b63def..7660e35 100644 --- a/rein/html/js/rate.js +++ b/rein/html/js/rate.js @@ -72,6 +72,7 @@ function nextJob() { document.addEventListener("DOMContentLoaded", function(event) { // Initialize contents of the job and user id fields and their labels $(".ratingdiv").raty(); + $(".ratingdiv").raty({score: 1}); $(".ratingdiv").click(function() { $("input[name='rating']").val($(".ratingdiv").raty('score')); }); diff --git a/rein/lib/forms.py b/rein/lib/forms.py index e104525..eab92ac 100644 --- a/rein/lib/forms.py +++ b/rein/lib/forms.py @@ -88,5 +88,5 @@ class RatingForm(Form): job_id = TextField(_('Select job'), validators = [Required()], default='') user_id = TextField(_('Select user'), validators = [Required(), avoid_self_rating], default='') rated_by_id = TextField(_('Your SIN'), validators = [Required()], default='') - rating = TextField(_('Rating'), validators=[Required()], default=0, widget=HiddenInput()) + rating = TextField(_('Rating'), validators=[Required()], default=1, widget=HiddenInput()) comments = TextAreaField(_('Comments'), validators = [], default='')