Skip to content

Commit

Permalink
Merge pull request #21 from eduNEXT/and/team_aware
Browse files Browse the repository at this point in the history
And/team aware
  • Loading branch information
andrey-canon authored Apr 27, 2018
2 parents bd76cdd + fc7fd3c commit 8c48844
Show file tree
Hide file tree
Showing 8 changed files with 208 additions and 15 deletions.
63 changes: 63 additions & 0 deletions rocketc/api_teams.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
"""
Api for teams
"""
import os
import logging
import requests
from oauthlib.oauth2 import LegacyApplicationClient
from requests_oauthlib import OAuth2Session

LOG = logging.getLogger(__name__)
os.environ['OAUTHLIB_INSECURE_TRANSPORT'] = '1'


class ApiTeams(object): #pylint: disable=too-few-public-methods

headers = {}
API_PATH = 'api/team/v0'

def __init__(self, username, password, client_id, client_secret, # pylint: disable=too-many-arguments
server_url='http://127.0.0.1:8000'):
"""Creates a ApiTeams object"""
self.server_url = server_url
self.client_id = client_id
self.client_secret = client_secret
self.password = password
self.username = username
self.headers["Authorization"] = "{} {}".format(
"Bearer", self._get_token(server_url))

def _get_token(self, server_url):
"""This method get the Authorization token"""
client_id = self.client_id
client_secret = self.client_secret

oauth = OAuth2Session(
client=LegacyApplicationClient(client_id=client_id))
token_url = "/".join([server_url, "oauth2/access_token/"])

token = oauth.fetch_token(token_url=token_url,
client_id=client_id,
client_secret=client_secret,
username=self.username,
password=self.password)

LOG.info("The acces token is: %s", token["access_token"])

return token['access_token']

def _call_api_get(self, url_path):
"""This method return the response"""
url = "/".join([self.server_url, self.API_PATH, url_path])
return requests.get(url, headers=self.headers)

def get_user_team(self, course_id, username):
"""Get the user's team"""
course_id = course_id.to_deprecated_string().replace("+", "%2B")
url_path = "teams/?course_id={}&username={}".format(
course_id, username)
team_request = self._call_api_get(url_path)

if team_request.status_code == 200:
return team_request.json()["results"]
return team_request.json()
2 changes: 2 additions & 0 deletions rocketc/openedx_dependencies.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,5 @@
# pylint: disable=import-error
# pylint: disable=unused-import
from openedx.core.djangoapps.user_api.accounts.image_helpers import get_profile_image_urls_for_user
from lms.djangoapps.teams.models import CourseTeam, CourseTeamMembership
from xmodule.modulestore.django import modulestore
2 changes: 2 additions & 0 deletions rocketc/requirements/base.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
nose==1.3.7
django==1.8
requests==2.9.1
oauthlib==2.0.7
requests-oauthlib==0.8.0
git+https://github.com/edx/[email protected]#egg=XBlock==1.1.1
git+https://github.com/edx/[email protected]#egg=xblock-utils==1.0.5
git+https://github.com/edx/[email protected]#egg=opaque-keys==0.3.1
132 changes: 120 additions & 12 deletions rocketc/rocketc.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@
TO-DO: Write a description of what this XBlock is.
"""
import hashlib
import re
import logging
import re
import pkg_resources
import requests

from api_teams import ApiTeams # pylint: disable=relative-import

from django.conf import settings
from django.contrib.auth.models import User

Expand All @@ -17,6 +19,7 @@
from xblockutils.settings import XBlockWithSettingsMixin
from xblockutils.studio_editable import StudioEditableXBlockMixin


LOADER = ResourceLoader(__name__)
LOG = logging.getLogger(__name__)

Expand All @@ -43,22 +46,34 @@ class RocketChatXBlock(XBlock, XBlockWithSettingsMixin, StudioEditableXBlockMixi
)

default_channel = String(
display_name="Default Channel",
default="",
display_name="Specific Channel",
scope=Scope.content,
help="This field allows to select the channel that would be accesible in the unit",
values_provider=lambda self: self.get_groups(),
)
default_group_enable = Boolean(

ui_is_block = Boolean(
default=False,
scope=Scope.user_state,
help="This is the flag for the initial channel",
)

channel = String(
display_name="Select Channel",
default="Main View",
scope=Scope.content,
help="This field allows to select the channel that would be accesible in the unit",
values_provider=lambda self: self.channels_enabled(),
)

team_channel = String(
default=None,
scope=Scope.user_info,
)
salt = "HarryPotter_and_thePrisoner_of _Azkaban"

# Possible editable fields
editable_fields = ('default_channel', )
editable_fields = ('channel', 'default_channel')

def resource_string(self, path):
"""Handy helper for getting resources from our kit."""
Expand All @@ -80,7 +95,7 @@ def student_view(self, context=None):

context["response"] = self.init()
context["user_data"] = self.user_data
context["default_group_enable"] = self.default_group_enable
context["ui_is_block"] = self.ui_is_block
context["public_url_service"] = self.server_data["public_url_service"]

frag = Fragment(LOADER.render_template(
Expand Down Expand Up @@ -176,10 +191,16 @@ def user_data(self):
user_data = {}
user_data["email"] = user.emails[0]
user_data["role"] = runtime.get_user_role()
user_data["course_id"] = runtime.course_id
user_data["course"] = re.sub('[^A-Za-z0-9]+', '', runtime.course_id._to_string()) # pylint: disable=protected-access
user_data["username"] = user.opt_attrs['edx-platform.username']
user_data["anonymous_student_id"] = runtime.anonymous_student_id
user_data["default_group"] = self.default_channel

if self.channel == "Team Discussion":
user_data["default_group"] = self.team_channel
else:
user_data["default_group"] = self.default_channel

return user_data

@property
Expand Down Expand Up @@ -212,11 +233,9 @@ def init(self):
if response['success']:
response = response['data']
user_id = response['userId']
self._update_user(user_id, user_data["username"], user_data["email"])
self.add_to_course_group(
user_data["course"], user_id)
self.default_group_enable = self._add_to_default_group(
self.default_channel, user_id)

self._join_groups(user_id, user_data)

if user_data["role"] == "instructor" and self.rocket_chat_role == "user":
self.change_role(user_id, "bot")
return response
Expand Down Expand Up @@ -468,3 +487,92 @@ def _set_topic(self, group_id, topic):
response = self._request_rocket_chat(method, url_path, data)

LOG.info("Method Set Topic: %s with this data: %s", response, data)

def _teams_is_enabled(self):
"""
This method verifies if teams are available
"""
from openedx_dependencies import modulestore # pylint: disable=relative-import
try:
course_id = self.runtime.course_id # pylint: disable=no-member
except AttributeError:
return False

course = modulestore().get_course(course_id, depth=0)
teams_configuration = course.teams_configuration
LOG.info("Team is enabled result: %s", teams_configuration)
if "topics" in teams_configuration and teams_configuration["topics"]:
return True

return False

def _get_team(self, username, course_id):
"""
This method gets the user's team
"""
try:
user = self.xblock_settings["username"]
password = self.xblock_settings["password"]
client_id = self.xblock_settings["client_id"]
client_secret = self.xblock_settings["client_secret"]
except KeyError:
raise

server_url = settings.LMS_ROOT_URL

api = ApiTeams(user, password, client_id, client_secret, server_url)
team = api.get_user_team(course_id, username)
LOG.info("Get Team response: %s", team)
if team:
return team[0]
return None

def _add_to_team_group(self, user_id, username, course_id):
"""
Add the user to team's group in rocketChat
"""
team = self._get_team(username, course_id)

if team is None:
return False

group_name = "-".join(["Team", team["topic_id"], team["name"]])
group_info = self._search_rocket_chat_group(group_name)
self.team_channel = group_name

if group_info["success"]:
response = self._add_to_group(user_id, group_info['group']['_id'])
LOG.info("Add to team group response: %s", response)
return response["success"]

response = self._create_group(group_name, username)
LOG.info("Add to team group response: %s", response)
return response["success"]

def _join_groups(self, user_id, user_data):
"""
This methodd add the user to the diferent channels
"""
default_channel = self.default_channel
channel = self.channel

if channel == "Team Discussion" and self._teams_is_enabled():
self.ui_is_block = self._add_to_team_group(
user_id, user_data["username"], user_data["course_id"])

elif channel == "Specific Channel":
self.ui_is_block = self._add_to_default_group(default_channel, user_id)

else:
self.ui_is_block = False
self.add_to_course_group(user_data["course"], user_id)

self._update_user(user_id, user_data["username"], user_data["email"])

def channels_enabled(self):
"""
This method returns a list with the channel options
"""
if self._teams_is_enabled():
return ["Main View", "Team Discussion", "Specific Channel"]
return ["Main View", "Specific Channel"]
2 changes: 1 addition & 1 deletion rocketc/static/html/rocketc.html
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<div class="rocketc_block">
<center>
{% if default_group_enable%}
{% if ui_is_block%}

{% if "authToken" in response%}
<div class="embed-container">
Expand Down
18 changes: 18 additions & 0 deletions rocketc/static/js/src/studio_view.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,4 +47,22 @@ function StudioViewEdit(runtime, element) {
$("#select-default").attr("class", "button");
});

$("#xb-field-edit-channel").on("change", function() {

if(this.value === "Specific Channel"){
$("#xb-field-edit-default_channel").prop("disabled", false);
}else{
$("#xb-field-edit-default_channel").prop("disabled", true);
}
});

$(function ($) {

if( $( "#xb-field-edit-channel" ).val() === "Specific Channel"){
$("#xb-field-edit-default_channel").prop("disabled", false);
}else{
$("#xb-field-edit-default_channel").prop("disabled", true);
}

});
}
2 changes: 1 addition & 1 deletion setup.cfg
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[bumpversion]
current_version = 0.2.4
current_version = 0.2.5
commit = True
tag = True

Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

from setuptools import setup

__version__ = '0.2.4'
__version__ = '0.2.5'


def package_data(pkg, roots):
Expand Down

0 comments on commit 8c48844

Please sign in to comment.