Skip to content

Commit

Permalink
Merge branch 'develop' into new-gallery
Browse files Browse the repository at this point in the history
  • Loading branch information
kevinlee12 committed Feb 24, 2016
2 parents 892142d + f2c3fe1 commit 4df7f52
Show file tree
Hide file tree
Showing 121 changed files with 4,437 additions and 1,017 deletions.
2 changes: 2 additions & 0 deletions .pylintrc
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ bad-functions=apply,input

[FORMAT]

max-line-length=80

indent-string=' '

[SIMILARITIES]
Expand Down
2 changes: 2 additions & 0 deletions AUTHORS
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ Estelle Lee <[email protected]>
Frederik Creemers <[email protected]>
Google Inc.
Jacob Davis <[email protected]>
Jakub Osika <[email protected]>
Jasper Deng <[email protected]>
Jaysinh Shukla <[email protected]>
Jérôme (zolk232) <[email protected]>
Expand All @@ -40,6 +41,7 @@ Milagro Teruel <[email protected]>
Mungo Dewar <[email protected]>
Oskar Cieslik <[email protected]>
Philip Hayes <[email protected]>
Prasanna Patil <[email protected]>
Raine Hoover <[email protected]>
Reto Brunner <[email protected]>
Richard Cho <[email protected]>
Expand Down
48 changes: 48 additions & 0 deletions CHANGELOG
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,54 @@ This file contains a summary of changes to the Oppia code base. For a full chang

https://github.com/oppia/oppia/commits/master

v2.1.3 (31 Jan 2016)
--------------------
Learner page:
* Allow learners to make suggestions for changes to exploration content.
* Fix #1279: Fix a bug where long usernames in the info card overflow the tooltip.
* Fix #1332: Show only 1 decimal place for ratings.
* Show 'Unrated' in the exploration information card when an exploration has no ratings.

Gallery page:
* Fix #918: Redesign the 'no search results found' message.

Interactions:
* ImageClickInput: fix misalignment of clickable regions.
* MusicNotesInput: move the logic from the controller to the link function.
* CodeRepl:
- Fix #1383: Allow imports in the learner’s code.
- Fix #1327: Show prepended and appended code.
- Gray out prepended and appended code sections.
* Add rules for the Graph interaction to check if a graph is regular, acyclic, strongly connected or weakly connected.

Editor page:
* Fix #1090: Change the rule feedback editor to only require either feedback or a new destination, and add a warning sign to the answer group if neither is specified.
* Fix #1255: Add a “Saving…” indicator after the 'Save Changes' button is clicked.
* Remove the need to specify icon data URLs manually for RTE components.
* Put a gray overlay over the state and interaction editors when they are hovered over.
* Change popover placement for the intro tutorial.
* Make history graph legend non-clickable.
* Fix overlapping buttons in exploration settings.

Infrastructure:
* Add a push hook that runs the linter and frontend tests.
* Add a script to simplify releases by summarizing authors, commit messages, and schema, setup script, and storage model changes.
* Add a job to compute the number of commits done by each contributor in each exploration.
* Skip the SDK update in the e2e tests script.
* Add parallelization to the linter.
* Split up the frontend player view into separate files.
* Add ‘OpenJDK’ (for Skulpt) and ‘unzip’ to the prerequisite-installation script.
* Remove frontend tests for displaying dates in users’ locales.
* Add a frontend service for computing expression output types.

Demo explorations:
* Add a new demo exploration which contains every interaction Oppia currently supports (for testing purposes).
* Remove the cities exploration.
* Update the demo explorations list to be explicitly mapped by id.

Other:
* Update contribution instructions in CONTRIBUTING.md.


v2.1.2 (6 Jan 2016)
-------------------
Expand Down
8 changes: 6 additions & 2 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,12 @@ Here's how to make a one-off code change. (If you're working on a larger feature
git push origin {{YOUR BRANCH NAME}}
```
Before your code gets uploaded to GitHub, a script is automatically executed that checks the styling of all changed JavaScript and Python files and runs the front-end tests.
**If any of the tests fail, the push will be interrupted**. If this happens, fix the issues that the tests tell you about and **repeat the instructions above** ('commit' and then 'push')
Before your code gets uploaded to GitHub, a script is automatically executed that checks the styling of all changed JavaScript and Python files and runs the front-end tests. Run the push command in command line, and not GitHub's Desktop client, as the script needs access to other tools like pip.
**If any of the tests fail, the push will be interrupted**. If this happens, fix the issues that the tests tell you about and **repeat the instructions above** ('commit' and then 'push').
If you need some help with your code and therefore want to put non functioning code into your GitHub fork to show it to other developers, you can force a push with `git push origin {{YOUR BRANCH NAME}} --no-verify`.
4. **When your feature is ready to merge, create a pull request.**
Expand Down
2 changes: 2 additions & 0 deletions CONTRIBUTORS
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ Elizabeth Kemp <[email protected]>
Estelle Lee <[email protected]>
Frederik Creemers <[email protected]>
Jacob Davis <[email protected]>
Jakub Osika <[email protected]>
Jasper Deng <[email protected]>
Jaysinh Shukla <[email protected]>
Jeremy Emerson <[email protected]>
Expand All @@ -62,6 +63,7 @@ Mungo Dewar <[email protected]>
Oskar Cieslik <[email protected]>
Phil Wagner <[email protected]>
Philip Hayes <[email protected]>
Prasanna Patil <[email protected]>
Raine Hoover <[email protected]>
Reinaldo Aguiar <[email protected]>
Reto Brunner <[email protected]>
Expand Down
2 changes: 1 addition & 1 deletion app.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
application: oppiaserver
version: 2-1-2
version: 2-1-3
runtime: python27
api_version: 1
threadsafe: false
Expand Down
18 changes: 12 additions & 6 deletions core/controllers/base_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -146,24 +146,30 @@ def _get_current_time(unused_cls):
current_time = orig_time
token1 = base.CsrfTokenManager.create_csrf_token('uid', 'page1')
self.assertTrue(
base.CsrfTokenManager.is_csrf_token_valid('uid', 'page1', token1))
base.CsrfTokenManager.is_csrf_token_valid(
'uid', 'page1', token1))

current_time = orig_time + 100
token2 = base.CsrfTokenManager.create_csrf_token('uid', 'page2')
self.assertTrue(
base.CsrfTokenManager.is_csrf_token_valid('uid', 'page2', token2))
base.CsrfTokenManager.is_csrf_token_valid(
'uid', 'page2', token2))

current_time = orig_time + FORTY_EIGHT_HOURS_IN_SECS + PADDING
self.assertFalse(
base.CsrfTokenManager.is_csrf_token_valid('uid', 'page1', token1))
base.CsrfTokenManager.is_csrf_token_valid(
'uid', 'page1', token1))
self.assertTrue(
base.CsrfTokenManager.is_csrf_token_valid('uid', 'page2', token2))
base.CsrfTokenManager.is_csrf_token_valid(
'uid', 'page2', token2))

current_time = orig_time + 100 + FORTY_EIGHT_HOURS_IN_SECS + PADDING
self.assertFalse(
base.CsrfTokenManager.is_csrf_token_valid('uid', 'page1', token1))
base.CsrfTokenManager.is_csrf_token_valid(
'uid', 'page1', token1))
self.assertFalse(
base.CsrfTokenManager.is_csrf_token_valid('uid', 'page2', token2))
base.CsrfTokenManager.is_csrf_token_valid(
'uid', 'page2', token2))


class EscapingTest(test_utils.GenericTestBase):
Expand Down
3 changes: 2 additions & 1 deletion core/controllers/editor.py
Original file line number Diff line number Diff line change
Expand Up @@ -402,7 +402,8 @@ def put(self, exploration_id):
if new_member_username:
if not rights_manager.Actor(
self.user_id).can_modify_roles(
rights_manager.ACTIVITY_TYPE_EXPLORATION, exploration_id):
rights_manager.ACTIVITY_TYPE_EXPLORATION,
exploration_id):
raise self.UnauthorizedUserException(
'Only an owner of this exploration can add or change '
'roles.')
Expand Down
6 changes: 3 additions & 3 deletions core/controllers/editor_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -302,7 +302,7 @@ def _create_training_data(*arg):
'cmd': exp_domain.CMD_EDIT_STATE_PROPERTY,
'state_name': state_name,
'property_name': (
exp_domain.STATE_PROPERTY_INTERACTION_UNCLASSIFIED_ANSWERS),
exp_domain.STATE_PROPERTY_UNCLASSIFIED_ANSWERS),
'new_value': ['sad']
}],
'commit_message': 'Update confirmed unclassified answers',
Expand Down Expand Up @@ -330,7 +330,7 @@ def _create_training_data(*arg):
'cmd': exp_domain.CMD_EDIT_STATE_PROPERTY,
'state_name': state_name,
'property_name': (
exp_domain.STATE_PROPERTY_INTERACTION_UNCLASSIFIED_ANSWERS),
exp_domain.STATE_PROPERTY_UNCLASSIFIED_ANSWERS),
'new_value': []
}, {
'cmd': exp_domain.CMD_EDIT_STATE_PROPERTY,
Expand All @@ -357,7 +357,7 @@ def _create_training_data(*arg):
'cmd': exp_domain.CMD_EDIT_STATE_PROPERTY,
'state_name': state_name,
'property_name': (
exp_domain.STATE_PROPERTY_INTERACTION_UNCLASSIFIED_ANSWERS),
exp_domain.STATE_PROPERTY_UNCLASSIFIED_ANSWERS),
'new_value': ['sad']
}],
'commit_message': 'Update confirmed unclassified answers',
Expand Down
99 changes: 97 additions & 2 deletions core/controllers/feedback.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
"""Controllers for the feedback thread page."""

from core.controllers import base
from core.controllers import editor
from core.domain import exp_services
from core.domain import feedback_services


Expand All @@ -25,7 +27,8 @@ class ThreadListHandler(base.BaseHandler):

def get(self, exploration_id):
self.values.update({
'threads': feedback_services.get_threadlist(exploration_id)})
'threads': feedback_services.get_all_threads(
exploration_id, False)})
self.render_json(self.values)

@base.require_user
Expand Down Expand Up @@ -56,18 +59,27 @@ class ThreadHandler(base.BaseHandler):

def get(self, exploration_id, thread_id): # pylint: disable=unused-argument
self.values.update({
'messages': feedback_services.get_messages(thread_id)})
'messages': feedback_services.get_messages(
exploration_id, thread_id)})
self.values.update({
'suggestion': feedback_services.get_suggestion(
exploration_id, thread_id)})
self.render_json(self.values)

@base.require_user
def post(self, exploration_id, thread_id): # pylint: disable=unused-argument
suggestion = feedback_services.get_suggestion(exploration_id, thread_id)
text = self.payload.get('text')
updated_status = self.payload.get('updated_status')
if not text and not updated_status:
raise self.InvalidInputException(
'Text for the message must be specified.')
if suggestion and updated_status:
raise self.InvalidInputException(
'Suggestion thread status cannot be changed manually.')

feedback_services.create_message(
exploration_id,
thread_id,
self.user_id,
updated_status,
Expand Down Expand Up @@ -106,3 +118,86 @@ def get(self):
'cursor': new_urlsafe_start_cursor,
'more': more,
})


class SuggestionHandler(base.BaseHandler):
""""Handles operations relating to learner suggestions."""

PAGE_NAME_FOR_CSRF = 'player'

@base.require_user
def post(self, exploration_id):
feedback_services.create_suggestion(
exploration_id,
self.user_id,
self.payload.get('exploration_version'),
self.payload.get('state_name'),
self.payload.get('description'),
self.payload.get('suggestion_content'))
self.render_json(self.values)


class SuggestionActionHandler(base.BaseHandler):
""""Handles actions performed on threads with suggestions."""

PAGE_NAME_FOR_CSRF = 'editor'
_ACCEPT_ACTION = 'accept'
_REJECT_ACTION = 'reject'

@editor.require_editor
def put(self, exploration_id, thread_id):
action = self.payload.get('action')
if action == self._ACCEPT_ACTION:
exp_services.accept_suggestion(
self.user_id,
thread_id,
exploration_id,
self.payload.get('commit_message'))
elif action == self._REJECT_ACTION:
exp_services.reject_suggestion(
self.user_id, thread_id, exploration_id)
else:
raise self.InvalidInputException('Invalid action.')

self.render_json(self.values)


class SuggestionListHandler(base.BaseHandler):
"""Handles operations relating to list of threads with suggestions."""

PAGE_NAME_FOR_CSRF = 'editor'
_LIST_TYPE_OPEN = 'open'
_LIST_TYPE_CLOSED = 'closed'
_LIST_TYPE_ALL = 'all'

def _string_to_bool(self, has_suggestion):
if has_suggestion == 'true':
return True
elif has_suggestion == 'false':
return False
else:
return None

@base.require_user
def get(self, exploration_id):
threads = None
list_type = self.request.get('list_type')
has_suggestion = self._string_to_bool(
self.request.get('has_suggestion'))
if has_suggestion is None:
raise self.InvalidInputException(
'Invalid value for has_suggestion.')
if list_type == self._LIST_TYPE_OPEN:
threads = feedback_services.get_open_threads(
exploration_id, has_suggestion)
elif list_type == self._LIST_TYPE_CLOSED:
threads = feedback_services.get_closed_threads(
exploration_id, has_suggestion)
elif list_type == self._LIST_TYPE_ALL:
threads = feedback_services.get_all_threads(
exploration_id, has_suggestion)
else:
raise self.InvalidInputException('Invalid list type.')

self.values.update({'threads': threads})
self.render_json(self.values)
Loading

0 comments on commit 4df7f52

Please sign in to comment.