Skip to content

Commit

Permalink
Merge branch 'develop' into recommendations
Browse files Browse the repository at this point in the history
  • Loading branch information
wxyxinyu committed Jun 1, 2015
2 parents 63ca627 + 321637e commit a363505
Show file tree
Hide file tree
Showing 84 changed files with 1,741 additions and 804 deletions.
2 changes: 1 addition & 1 deletion .pylintrc
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
# pylint core --rcfile=.pylintrc -i y

[GENERAL]
init-hook='import sys; sys.path.append("../oppia_tools/google_appengine_1.9.11/google_appengine")'
init-hook='import sys; sys.path.append("../oppia_tools/google_appengine_1.9.19/google_appengine")'

[BASIC]

Expand Down
4 changes: 4 additions & 0 deletions AUTHORS
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@
# Please keep the list sorted alphabetically.

Alex Gower <[email protected]>
Allan Zhou <[email protected]>
Andrey Mironyuk <[email protected]>
Ben Targan <[email protected]>
Chase Albert <[email protected]>
Chin Zhan Xiong <[email protected]>
Debanshu Bhaumik <[email protected]>
Expand All @@ -25,6 +28,7 @@ Kumari Shalini <[email protected]>
Marcel Schmittfull <[email protected]>
Michael Mossey <[email protected]>
Michael Wagner <[email protected]>
Milagro Teruel <[email protected]>
Philip Hayes <[email protected]>
Samara Trilling <[email protected]>
Shafqat Dulal <[email protected]>
Expand Down
7 changes: 7 additions & 0 deletions CONTRIBUTORS
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,16 @@

Abraham Mgowano <[email protected]>
Alex Gower <[email protected]>
Allan Zhou <[email protected]>
Amit Deutsch <[email protected]>
Andrey Mironyuk <[email protected]>
Angela Park <[email protected]>
Ben Henning <[email protected]>
Ben Targan <[email protected]>
Chase Albert <[email protected]>
Chin Zhan Xiong <[email protected]>
Debanshu Bhaumik <[email protected]>
Elizabeth Kemp <[email protected]>
Estelle Lee <[email protected]>
Frederik Creemers <[email protected]>
Jacob Davis <[email protected]>
Expand All @@ -43,6 +48,7 @@ Marcel Schmittfull <[email protected]>
Michael Anuzis <[email protected]>
Michael Mossey <[email protected]>
Michael Wagner <[email protected]>
Milagro Teruel <[email protected]>
Phil Wagner <[email protected]>
Philip Hayes <[email protected]>
Reinaldo Aguiar <[email protected]>
Expand All @@ -55,4 +61,5 @@ Tarashish Mishra <[email protected]>
Wilson Hong <[email protected]>
Xinyu Wu <[email protected]>
Yana Malysheva <[email protected]>
Yuan Gu <[email protected]>
Zoe Madden-Wood <[email protected]>
6 changes: 6 additions & 0 deletions app.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,12 @@ handlers:
http_headers:
Cache-Control: 'public, max-age=2592000'
Vary: Accept-Encoding
- url: /extensions/gadgets/(.*)/static/(.*)
static_files: extensions/gadgets/\1/static/\2
upload: extensions/gadgets/(.*)/static/(.*)
secure: always
http_headers:
Cache-Control: 'no-cache'
- url: /extensions/interactions/(.*)/static/(.*)
static_files: extensions/interactions/\1/static/\2
upload: extensions/interactions/(.*)/static/(.*)
Expand Down
8 changes: 8 additions & 0 deletions core/controllers/editor.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
from core.domain import exp_domain
from core.domain import exp_services
from core.domain import fs_domain
from core.domain import gadget_registry
from core.domain import interaction_registry
from core.domain import rights_manager
from core.domain import rte_component_registry
Expand Down Expand Up @@ -194,6 +195,10 @@ def get(self, exploration_id):
interaction_registry.Registry.get_validators_html(
interaction_ids))

gadget_ids = gadget_registry.Registry.get_all_gadget_ids()
gadget_templates = (
gadget_registry.Registry.get_gadget_html(gadget_ids))

skin_templates = skins_services.Registry.get_skin_templates(
skins_services.Registry.get_all_skin_ids())

Expand All @@ -216,6 +221,7 @@ def get(self, exploration_id):
'can_unpublish': rights_manager.Actor(self.user_id).can_unpublish(
exploration_id),
'dependencies_html': jinja2.utils.Markup(dependencies_html),
'gadget_templates': jinja2.utils.Markup(gadget_templates),
'interaction_templates': jinja2.utils.Markup(
interaction_templates),
'interaction_validators_html': jinja2.utils.Markup(
Expand Down Expand Up @@ -276,6 +282,8 @@ def _get_exploration_data(self, exploration_id, version=None):
'show_state_editor_tutorial_on_load': (
self.user_id and not
self.user_has_started_state_editor_tutorial),
'skin_customizations': exploration.skin_instance.to_dict()[
'skin_customizations'],
'states': states,
'tags': exploration.tags,
'title': exploration.title,
Expand Down
10 changes: 6 additions & 4 deletions core/controllers/home.py
Original file line number Diff line number Diff line change
Expand Up @@ -127,9 +127,10 @@ def get(self):
if self.user_id is None:
raise self.PageNotFoundException

editable_exp_summaries = (
exp_services.get_at_least_editable_exploration_summaries(
self.user_id))
subscribed_summaries = (
exp_services.get_exploration_summaries_matching_ids(
subscription_services.get_activity_ids_subscribed_to(
self.user_id)))

def _get_intro_card_color(category):
return (
Expand All @@ -138,7 +139,8 @@ def _get_intro_card_color(category):
feconf.DEFAULT_COLOR)

explorations_list = []
for exp_summary in editable_exp_summaries.values():

for exp_summary in subscribed_summaries:
feedback_thread_analytics = feedback_services.get_thread_analytics(
exp_summary.id)
explorations_list.append({
Expand Down
7 changes: 7 additions & 0 deletions core/controllers/reader.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
from core.domain import exp_services
from core.domain import feedback_services
from core.domain import fs_domain
from core.domain import gadget_registry
from core.domain import interaction_registry
from core.domain import param_domain
from core.domain import rating_services
Expand Down Expand Up @@ -175,6 +176,7 @@ def get(self, exploration_id):
is_iframed = (self.request.get('iframed') == 'true')

# TODO(sll): Cache these computations.
gadget_ids = exploration.get_gadget_ids()
interaction_ids = exploration.get_interaction_ids()
dependency_ids = (
interaction_registry.Registry.get_deduplicated_dependency_ids(
Expand All @@ -183,12 +185,16 @@ def get(self, exploration_id):
dependency_registry.Registry.get_deps_html_and_angular_modules(
dependency_ids))

gadget_templates = (
gadget_registry.Registry.get_gadget_html(gadget_ids))

interaction_templates = (
rte_component_registry.Registry.get_html_for_all_components() +
interaction_registry.Registry.get_interaction_html(
interaction_ids))

self.values.update({
'GADGET_SPECS': gadget_registry.Registry.get_all_specs(),
'INTERACTION_SPECS': interaction_registry.Registry.get_all_specs(),
'SHARING_OPTIONS': SHARING_OPTIONS.value,
'SHARING_OPTIONS_TWITTER_TEXT': SHARING_OPTIONS_TWITTER_TEXT.value,
Expand All @@ -202,6 +208,7 @@ def get(self, exploration_id):
dependencies_html),
'exploration_title': exploration.title,
'exploration_version': version,
'gadget_templates': jinja2.utils.Markup(gadget_templates),
'iframed': is_iframed,
'interaction_templates': jinja2.utils.Markup(
interaction_templates),
Expand Down
30 changes: 27 additions & 3 deletions core/domain/exp_domain.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@

__author__ = 'Sean Lip'

import collections
import copy
import logging
import re
Expand Down Expand Up @@ -603,6 +604,18 @@ def validate(self):
'%s gadget not visible in any states.' % (
self.gadget.name))

# Validate state name visibility isn't repeated within each gadget.
if len(self.visible_in_states) != len(set(self.visible_in_states)):
redundant_visible_states = [
state_name for state_name, count
in collections.Counter(self.visible_in_states).items()
if count > 1]
raise utils.ValidationError(
'%s specifies visibility repeatedly for state%s: %s' % (
self.id,
's' if len(redundant_visible_states) > 1 else '',
', '.join(redundant_visible_states)))

def to_dict(self):
"""Returns GadgetInstance data represented in dict form."""
return {
Expand Down Expand Up @@ -674,8 +687,7 @@ def validate(self):
gadget_instance.validate()

def to_dict(self):
"""Returns SkinInstance data represented in dict form.
"""
"""Returns SkinInstance data represented in dict form."""
return {
'skin_id': self.skin_id,
'skin_customizations': {
Expand Down Expand Up @@ -1636,17 +1648,29 @@ def to_player_dict(self):
'init_state_name': self.init_state_name,
'param_changes': self.param_change_dicts,
'param_specs': self.param_specs_dict,
'skin_customizations': self.skin_instance.to_dict()[
'skin_customizations'],
'states': {
state_name: state.to_dict()
for (state_name, state) in self.states.iteritems()
},
'title': self.title,
}

def get_gadget_ids(self):
"""Get all gadget ids used in this exploration."""
result = set()
for gadget_instances_list in (
self.skin_instance.panel_contents_dict.itervalues()):
result.update([
gadget_instance.id for gadget_instance
in gadget_instances_list])
return sorted(result)

def get_interaction_ids(self):
"""Get all interaction ids used in this exploration."""
return list(set([
state.interaction.id for state in self.states.values()]))
state.interaction.id for state in self.states.itervalues()]))


class ExplorationSummary(object):
Expand Down
33 changes: 32 additions & 1 deletion core/domain/exp_domain_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -396,6 +396,15 @@ def test_exploration_skin_and_gadget_validation(self):
exploration.states['GHI'] = ghi_state
exploration.validate()

gadget_instance.visible_in_states.extend(['GHI'])
with self.assertRaisesRegexp(
utils.ValidationError,
'TestGadget specifies visibility repeatedly for state: GHI'):
exploration.validate()

# Remove duplicate state.
gadget_instance.visible_in_states.pop()

# Adding a panel that doesn't exist in the skin.
exploration.skin_instance.panel_contents_dict[
'non_existent_panel'] = []
Expand All @@ -405,6 +414,27 @@ def test_exploration_skin_and_gadget_validation(self):
'non_existent_panel panel not found in skin conversation_v1'):
exploration.validate()

def test_exploration_get_gadget_ids(self):
"""Test that Exploration.get_gadget_ids returns apt results."""
exploration_without_gadgets = exp_domain.Exploration.from_yaml(
'An Exploration ID', 'A title', 'Category', SAMPLE_YAML_CONTENT)
self.assertEqual(exploration_without_gadgets.get_gadget_ids(), [])

exploration_with_gadgets = exp_domain.Exploration.from_yaml(
'exp1', 'Title', 'Category', SAMPLE_YAML_CONTENT_WITH_GADGETS)
self.assertEqual(
exploration_with_gadgets.get_gadget_ids(),
['TestGadget']
)

another_gadget = exp_domain.GadgetInstance('AnotherGadget', [], {})
exploration_with_gadgets.skin_instance.panel_contents_dict[
'right'].append(another_gadget)
self.assertEqual(
exploration_with_gadgets.get_gadget_ids(),
['AnotherGadget', 'TestGadget']
)

def test_objective_validation(self):
"""Test that objectives are validated only in 'strict' mode."""
self.save_new_valid_exploration(
Expand Down Expand Up @@ -865,6 +895,7 @@ def _get_default_state_dict(content_str, dest_name):
},
'param_changes': [],
'param_specs': {},
'skin_customizations': feconf.DEFAULT_SKIN_CUSTOMIZATIONS,
})


Expand Down Expand Up @@ -1047,7 +1078,7 @@ def test_gadget_instance_validation(self):
panel_contents_dict['left'].append(test_gadget_instance)
with self.assertRaisesRegexp(
utils.ValidationError,
"'left' panel expected at most 1 gadget, received 2."):
"'left' panel expected at most 1 gadget, but 2 gadgets are visible in state 'New state'."):
exploration.validate()

# Assert that an error is raised when a gadget is not visible in any
Expand Down
16 changes: 12 additions & 4 deletions core/domain/exp_services.py
Original file line number Diff line number Diff line change
Expand Up @@ -600,6 +600,8 @@ def _save_exploration(
exploration_model.blurb = exploration.blurb
exploration_model.author_notes = exploration.author_notes
exploration_model.default_skin = exploration.default_skin
exploration_model.skin_customizations = (
exploration.skin_instance.to_dict()['skin_customizations'])

exploration_model.init_state_name = exploration.init_state_name
exploration_model.states = {
Expand Down Expand Up @@ -638,6 +640,8 @@ def _create_exploration(
blurb=exploration.blurb,
author_notes=exploration.author_notes,
default_skin=exploration.default_skin,
skin_customizations=exploration.skin_instance.to_dict(
)['skin_customizations'],
init_state_name=exploration.init_state_name,
states={
state_name: state.to_dict()
Expand Down Expand Up @@ -1063,11 +1067,14 @@ def _get_search_rank(exp_id):
"""
# TODO(sll): Improve this calculation.
_STATUS_PUBLICIZED_BONUS = 30
# This is done to prevent the rank hitting 0 too easily. Note that
# negative ranks are disallowed in the Search API.
_DEFAULT_RANK = 20

exploration = get_exploration_by_id(exp_id)
rights = rights_manager.get_exploration_rights(exp_id)
summary = get_exploration_summary_by_id(exp_id)
rank = (
rank = _DEFAULT_RANK + (
_STATUS_PUBLICIZED_BONUS
if rights.status == rights_manager.EXPLORATION_STATUS_PUBLICIZED
else 0)
Expand All @@ -1079,16 +1086,17 @@ def _get_search_rank(exp_id):
summary.ratings[rating_value] *
RATING_WEIGHTINGS[rating_value])

_BEGINNING_OF_TIME = datetime.datetime(2013, 6, 30)
time_delta_days = int((exploration.last_updated - _BEGINNING_OF_TIME).days)
_TIME_NOW = datetime.datetime.utcnow()
time_delta_days = int((_TIME_NOW - exploration.last_updated).days)
if time_delta_days == 0:
rank += 80
elif time_delta_days == 1:
rank += 50
elif 2 <= time_delta_days <= 7:
rank += 35

return rank
# Ranks must be non-negative.
return max(rank, 0)


def _exp_to_search_dict(exp):
Expand Down
Loading

0 comments on commit a363505

Please sign in to comment.