ws: update web-service API to latest specifications

This commit is contained in:
Benjamin Dauvergne 2012-11-06 15:37:38 +01:00
parent b5f33cf68d
commit 5484011502
2 changed files with 176 additions and 121 deletions

View File

@ -1,121 +1 @@
import requests
import os.path
import xml.etree.ElementTree as etree
import collections
import logging
CourseByOwnerResponse = collections.namedtuple('CourseByOwnerResponse',
('message', 'courses'))
Course = collections.namedtuple('Course',
('id', 'name', 'available'))
logger = logging.getLogger(__name__)
def bool2str(b):
return 'YES' if b else 'NO'
class BlackboardConnector(object):
def __init__(self, url, shared_key):
self.url = url
self.shared_key = shared_key
def _get_course_helper(self, r):
r.encoding = 'utf-8'
if r.status_code == 200:
x = etree.XML(r.text.encode('utf-8'))
info_message_elt = x.find('infoMessage')
course_elts = x.findall('*/course')
courses = []
for course_elt in course_elts:
id_elt = course_elt.find('ID')
name_elt = course_elt.find('name')
available_elt = course_elt.find('available')
if None in (id_elt, name_elt, available_elt) or available_elt.text not in ('YES', 'NO'):
logger.error('invalid answer to GetCourseByOwner: %r', r.text)
return False, 'Erreur BlackBoard'
course = Course(id_elt.text.strip(), name_elt.text.strip(),
available_elt.text == 'YES')
courses.append(course)
return True, CourseByOwnerResponse(info_message_elt.text.strip(),
courses)
elif r.status_code == 400:
return False, r.text
else:
logging.error('BlackBoard code HTTP %s', r.status_code)
return False, 'Erreur BlackBoard'
def get_course_by_owner(self, user_login):
assert user_login
url = os.path.join(self.url, 'GetCourseByOwner')
logging.debug('sending request %s', url)
r = requests.get(url, params={'user_login':
user_login.encode('ascii')})
return self._get_course_helper(r)
def get_course_by_ue(self, entity_code):
assert entity_code
url = os.path.join(self.url, 'GetCourseByUE')
logging.debug('sending request %s', url)
r = requests.get(url,
params={'UE_ID': entity_code.encode('ascii')})
return self._get_course_helper(r)
def send_file(self, uploadfile, courses_id):
assert hasattr(uploadfile, 'read')
assert hasattr(courses_id, '__iter__')
assert len(courses_id) > 0
assert all(map(bool, courses_id))
url = os.path.join(self.url, 'SendFile')
r = requests.post(url, params={'course_ID': courses_id},
files={'uploadfile': uploadfile})
if r.status_code == 200:
return True, r.text
return False, r.text
def create_course(self, course_id, course_name, category,
open_to_visitors=True, auto_inscription=True, password=None):
assert isinstance(course_id, unicode) and course_id
assert isinstance(course_name, unicode) and course_name
assert isinstance(category, unicode) and unicode
open_to_visitors = bool2str(open_to_visitors)
auto_inscription = bool2str(auto_inscription)
params = {
'course_ID': course_id,
'course_name': course_name,
'open_to_visitors': open_to_visitors,
'auto_inscription': auto_inscription,
'category': category,
}
if password:
params['password'] = password
url = os.path.join(self.url, 'CreateCourse')
r = requests.post(url, params=params)
if r.status_code == 200:
return True, r.text
return False, r.text
def get_categories(self):
return True, []
if __name__ == '__main__':
import sys
import logging
logging.basicConfig(level=logging.DEBUG)
try:
connector = BlackboardConnector(sys.argv[1])
if len(sys.argv) == 4 and sys.argv[2] == 'GetCourseByOwner':
print connector.get_course_by_owner(sys.argv[3])
elif len(sys.argv) == 4 and sys.argv[2] == 'GetCourseByUE':
print connector.get_course_by_ue(sys.argv[3])
elif len(sys.argv) == 5 and sys.argv[2] == 'SendFile':
print connector.send_file(file(sys.argv[3]), sys.argv[4].split(','))
else:
raise ValueError
except:
print 'Syntax: python', sys.argv[0], '<url> [GetCourseByOwner <user_login>|GetCourseByUE <UE_ID>|SendFile <filename> <courseid1,courseid2,courseid3,etc.>]'
__VERSION__ = (0, 1, 0)

175
polynum_blackboard/ws.py Normal file
View File

@ -0,0 +1,175 @@
import requests
import os.path
import xml.etree.ElementTree as etree
import collections
import logging
CourseByOwnerResponse = collections.namedtuple('CourseByOwnerResponse',
('message', 'courses'))
Course = collections.namedtuple('Course',
('id', 'name', 'available'))
GetCategoryResponse = collections.namedtuple('GetCategoryResponse',
('message', 'categories'))
Category = collections.namedtuple('Category',
('id', 'name'))
logger = logging.getLogger(__name__)
def bool2str(b):
return 'YES' if b else 'NO'
class BlackboardConnector(object):
def __init__(self, url, login=None, password=None, shared_key=None):
self.url = url
self.login = login
self.password = password
self.shared_key = shared_key
self.session = requests.session()
url = os.path.join(self.url, 'login/')
print url
self.session.post(url,
params=dict(user_id=self.login,
password=self.password, action='login'))
# print login
# print r.status_code
# print self.session.__dict__
def _get_course_helper(self, r):
r.encoding = 'utf-8'
if r.status_code == 200:
try:
x = etree.XML(r.content)
except etree.ParseError:
print 'Parse Error', r.content, r.status_code
raise
info_message_elt = x.find('infoMessage')
course_elts = x.findall('*/course')
courses = []
for course_elt in course_elts:
id_elt = course_elt.find('ID')
name_elt = course_elt.find('name')
available_elt = course_elt.find('available')
if None in (id_elt, name_elt, available_elt) or available_elt.text not in ('YES', 'NO'):
logger.error('invalid answer to GetCourseByOwner: %r', r.text)
return False, 'Erreur BlackBoard'
course = Course(id_elt.text.strip(), name_elt.text.strip(),
available_elt.text == 'YES')
courses.append(course)
return True, CourseByOwnerResponse(info_message_elt.text.strip(),
courses)
elif r.status_code == 400:
return False, r.text
else:
logging.error('BlackBoard code HTTP %s', r.status_code)
return False, 'Erreur BlackBoard'
def get_course_by_owner(self, user_login):
r = self.send_request('GetCoursesByOwner',
user_login=user_login.encode('ascii'))
return self._get_course_helper(r)
def get_course_by_ue(self, entity_code):
r = self.send_request('GetCoursesByOwner',
UE_ID=entity_code.encode('ascii'))
return self._get_course_helper(r)
def send_file(self, uploadfile, courses_id):
assert hasattr(uploadfile, 'read')
assert hasattr(courses_id, '__iter__')
assert len(courses_id) > 0
assert all(map(bool, courses_id))
r = self.send_request('SendFile', course_ID=courses_id,
files=dict(uploadfile=uploadfile), method='post')
if r.status_code == 200:
return True, r.text
return False, r.text
def create_course(self, course_id, course_name, category,
open_to_visitors=True, auto_inscription=True, password=None):
assert isinstance(course_id, unicode) and course_id
assert isinstance(course_name, unicode) and course_name
assert isinstance(category, unicode) and unicode
open_to_visitors = bool2str(open_to_visitors)
auto_inscription = bool2str(auto_inscription)
params = {
'course_ID': course_id,
'course_name': course_name,
'open_to_visitors': open_to_visitors,
'auto_inscription': auto_inscription,
'category': category,
}
if password:
params['password'] = password
r = self.send_request('CreateCourse', **params)
if r.status_code == 200:
return True, r.text
return False, r.text
def send_request(self, request_name, **params):
params['secret_key'] = self.shared_key
kwargs = { 'params': params }
files = params.pop('files', None)
method = params.pop('method', 'get')
if files:
kwargs['files'] = files
url = os.path.join(self.url, 'ui-ui-Polynum-BBLEARN/app', request_name)
logging.debug('sending request %s', url)
r = getattr(self.session, method)(url, **kwargs)
print 'content', r.content
r.encoding = 'utf-8'
if r.status_code == 500:
print r.text
return r
def get_categories(self):
r = self.send_request('GetCategories')
if r.status_code == 200:
x = etree.XML(r.content)
info_message_elt = x.find('infoMessage')
category_elts = x.findall('categories/category')
categories = []
for category_elt in category_elts:
id_elt = category_elt.find('ID')
name_elt = category_elt.find('name')
category = Category(id_elt.text.strip(),
name_elt.text.strip())
categories.append(category)
return True, GetCategoryResponse(info_message_elt.text.strip(),
categories)
elif r.status_code == 400:
return False, r.text
else:
print r.text
logging.error('BlackBoard code HTTP %s', r.status_code)
return False, 'Erreur BlackBoard {0}'.format(r.status_code)
if __name__ == '__main__':
import sys
import logging
import pprint
logging.basicConfig(level=logging.DEBUG)
try:
connector = BlackboardConnector(sys.argv[1], *sys.argv[2:5])
if len(sys.argv) == 7 and sys.argv[5] == 'GetCoursesByOwner':
ok, response = pprint.pprint(connector.get_course_by_owner(sys.argv[6])[1])
elif len(sys.argv) == 7 and sys.argv[5] == 'GetCoursesByUE':
ok, response = connector.get_course_by_ue(sys.argv[6])
elif len(sys.argv) == 8 and sys.argv[5] == 'SendFile':
ok, text = connector.send_file(file(sys.argv[6]), sys.argv[7].split(','))
elif len(sys.argv) == 6 and sys.argv[5] == 'GetCategories':
ok, response = connector.get_categories()
else:
raise ValueError
if ok:
print 'OK'
else:
print 'NOK'
print response
except Exception, e:
raise
print 'Syntax: python', sys.argv[0], '<url> [GetCoursesByOwner <user_login>|GetCoursesByUE <UE_ID>|SendFile <filename> <courseid1,courseid2,courseid3,etc.>]'