def get_assignments(self, verbose=True, keep_cache=True): if 'course_id' not in self.config.keys(): raise ClientError('No course pointed!') filename = 'assignments_{}.json'.format(self.config['course_id']) filepath = Client.downloads_path / filename if filepath.exists() and keep_cache: with open(filepath, 'r') as fd: assignments = json.load(fd) else: if not self.is_authenticate(): raise ClientError('Not authenticated yet!') web_service = ws.WS(self.config['domain'], self.config['token']) # mod_assign_get_assignments requires a list of course ids, but we supply only one assignments = web_service.mod_assign_get_assignments( [self.config['course_id']]) assignments = assignments['courses'][0] Client.save_data(assignments, filename) if verbose: for asn in assignments['assignments']: print(asn['id'], asn['name']) return [{ 'id': asn['id'], 'name': asn['name'], 'cutoffdate': datetime.fromtimestamp(int(asn['cutoffdate'])) } for asn in assignments['assignments']]
def get_modules(self, verbose=True, keep_cache=True): if 'course_id' not in self.config.keys(): raise ClientError('No course pointed!') filename = 'modules_{}.json'.format(self.config['course_id']) filepath = Client.downloads_path / filename if filepath.exists() and keep_cache: with open(filepath, 'r') as fd: modules = json.load(fd) else: if not self.is_authenticate(): raise ClientError('Not authenticated yet!') web_service = ws.WS(self.config['domain'], self.config['token']) contents = web_service.core_course_get_contents( self.config['course_id']) # contents is a list of blocks, each containing some modules modules = [m for content in contents for m in content['modules']] Client.save_data(modules, filename) if verbose: for mod in modules: print(f"{mod['id']} -{mod['instance']:>7}", mod['name']) return [{ 'id': mod['id'], 'instance': mod['instance'], 'name': mod['name'] } for mod in modules]
def get_submissions(self, asn_id, verbose=True, keep_cache=True): if 'course_id' not in self.config.keys(): raise ClientError('No course pointed!') if asn_id not in [ asn['id'] for asn in self.get_assignments(verbose=False) ]: raise ClientError('Invalid assignment id!') filename = 'submissions_{}_{}.json'.format(self.config['course_id'], asn_id) filepath = Client.downloads_path / filename if filepath.exists() and keep_cache: with open(filepath, 'r') as fd: submissions = json.load(fd) else: if not self.is_authenticate(): raise ClientError('Not authenticated yet!') web_service = ws.WS(self.config['domain'], self.config['token']) # mod_assign_get_submissions requires a list of assignment ids, # but we supply only one submissions = web_service.mod_assign_get_submissions([asn_id]) submissions = submissions['assignments'][0] Client.save_data(submissions, filename) if verbose: for sub in submissions['submissions']: print(sub['userid'], sub['status'], sub['gradingstatus']) return [{ 'userid': sub['userid'], 'status': sub['status'], 'gradingstatus': sub['gradingstatus'], } for sub in submissions['submissions']]
def get_enrolled(self, verbose=True, keep_cache=True): if 'course_id' not in self.config.keys(): raise ClientError('No course pointed!') filename = 'enrolled_{}.json'.format(self.config['course_id']) filepath = Client.downloads_path / filename if filepath.exists() and keep_cache: with open(filepath, 'r') as fd: enrolled_users = json.load(fd) else: if not self.is_authenticate(): raise ClientError('Not authenticated yet!') web_service = ws.WS(self.config['domain'], self.config['token']) enrolled_users = web_service.core_enrol_get_enrolled_users( self.config['course_id']) Client.save_data(enrolled_users, filename) if verbose: for user in enrolled_users: print( user['id'], ' '.join( [w.capitalize() for w in user['fullname'].split(' ')]), '({})'.format('.'.join( [r['shortname'] for r in user['roles']]))) return [{ 'userid': user['id'], 'firstname': user['firstname'], 'lastname': user['lastname'], 'roles': '.'.join([r['shortname'] for r in user['roles']]), 'idnumber': user.get('idnumber', 0) } for user in enrolled_users]
def __init__(self): self.init = json.load(open("ws.ini", "rw")) self.init_logging = self.init["Init"]["Logging"] self.init_logfile = self.init["Init"]["Logfile"] self.init_rain = self.init["Init"]["Total rain"] self.prev_rain = 0 logging.basicConfig(level=logging.DEBUG) if self.init_logging == "DEBUG" \ else logging.basicConfig(level=logging.INFO) self.logger = logging.getLogger('WS1080') fh = RotatingFileHandler(self.init_logfile, mode='a', maxBytes=5 * 1024 * 1024, backupCount=2) fh.setLevel(logging.DEBUG) ch = logging.StreamHandler() ch.setLevel(logging.DEBUG) formatter = logging.Formatter('%(asctime)s %(name)s %(levelname)s - %(message)s') fh.setFormatter(formatter) ch.setFormatter(formatter) self.logger.addHandler(fh) self.logger.addHandler(ch) self.ws = ws.WS() self.timer = util.RepeatTimer(WS1080_UPDATE_INTERVAL, self.sync) self.timer.start() self.client = MongoClient() self.db_weather = self.client.WS self.cl_min = self.db_weather.minute self.cl_hourly = self.db_weather.hourly self.cl_daily = self.db_weather.daily self.cl_monthly = self.db_weather.monthly self.cl_yearly = self.db_weather.yearly
def authenticate(self, username, password): # We need a domain in order to ask for authentication if 'domain' not in self.config.keys() or not self.config['domain']: raise ClientError('Moodle Domain not inserted!') service_name = 'moodle_mobile_app' web_service = ws.WS(self.config['domain']) web_service.authenticate(user=username, password=password, service=service_name) self.config['token'] = web_service.token
def get_site_info(self): if not self.is_authenticate(): raise ClientError('Not authenticated yet!') web_service = ws.WS(self.config['domain'], self.config['token']) site_info = web_service.core_webservice_get_site_info() Client.save_data(site_info, 'site_info.json') self.config['user'] = { 'userid': site_info.get('userid', ""), 'username': site_info.get('username', ""), 'email': site_info.get('email', ""), 'first': site_info.get('firstname', ""), 'last': site_info.get('lastname', ""), 'full': site_info.get('fullname', ""), }
def start(self, gps_rate=None): # User login #self.user_name = self._gui.waitForLogin() # < blocking tempUser = '******' % gma() self.user_name = "picker_" + tempUser.replace(':', '') print("User: "******"wss://lcas.lincoln.ac.uk/car/ws", user_name=self.user_name, update_orders_cb=self.update_orders_cb) # setup the main gui window self._gui.setupMainWindow() self._gui.setUser("User: "******"Welcome to Call A Robot.") # start gps thread self._gps.start() # start ws thread self._ws.start() print("Initialization complete") if gps_rate is None: ## we want gps readings as soon as they arrive self._gps.set_callback(self._ws.send_gps) # start gui thread (tkinter only runs on the main thread :-( ) self._gui.loopMainWindow() # < blocking else: ## we want gps readings at a certain rate seconds = 1. / float(gps_rate) while self._gps.has_more_data(): lat, lon, epx, epy, ts = self._gps.get_latest_data() self._ws.send_gps(lat, lon, epx, epy, ts) time.sleep(seconds)
def main(): try: consensus_server = ConsensusServer() ws_server = ws.WS(consensus_server.handle_msg) ws_thread = threading.Thread(target=ws_server.start) ws_thread.daemon = True ws_thread.start() http_server = hs.HTTP() http_thread = threading.Thread(target=http_server.start) http_thread.daemon = True http_thread.start() consensus_server.start() except KeyboardInterrupt: print("^C received, shutting down server") ws_server.stop()
def get_courses(self, verbose=True, keep_cache=True): filename = 'users_courses.json' filepath = Client.downloads_path / filename if filepath.exists() and keep_cache: with open(filepath, 'r') as fd: users_courses = json.load(fd) else: if not self.is_authenticate(): raise ClientError('Not authenticated yet!') web_service = ws.WS(self.config['domain'], self.config['token']) if 'user' not in self.config.keys(): self.get_site_info() params = {'userid': self.config['user']['userid']} users_courses = web_service.make_request( 'core_enrol_get_users_courses', params) Client.save_data(users_courses, filename) if verbose: for course in users_courses: print("{:>7} : {}".format(course['id'], course['shortname'])) return [course['id'] for course in users_courses]
def get_activities_completions(self, verbose=True, keep_cache=True): if 'course_id' not in self.config.keys(): raise ClientError('No course pointed!') filename = 'activities_completions_{}.json'.format( self.config['course_id']) filepath = Client.downloads_path / filename if filepath.exists() and keep_cache: with open(filepath, 'r') as fd: activities_completions = json.load(fd) else: if not self.is_authenticate(): raise ClientError('Not authenticated yet!') web_service = ws.WS(self.config['domain'], self.config['token']) activities_completions = {} for user in self.get_enrolled(verbose=False): statuses_and_warnings = web_service.\ core_completion_get_activities_completion_status(self.config['course_id'], user['userid']) activities_completions[ user['userid']] = statuses_and_warnings['statuses'] Client.save_data(activities_completions, filename) if verbose: for user_ac in activities_completions.values(): for ac in user_ac: print(ac['cmid'], ac['instance'], ac['state'], ac['timecompleted']) return { user_id: [{ 'cmid': ac['cmid'], 'instance': ac['instance'], 'state': ac['state'], 'timecompleted': datetime.fromtimestamp(int(ac['timecompleted'])) } for ac in user_ac] for user_id, user_ac in activities_completions.items() }
def start(self): # get user to login self.user_name = _gui.waitForLogin() # < blocking # init websocket self._ws = ws.WS(address="wss://lcas.lincoln.ac.uk/car/ws", user_name=self.user_name, update_orders_cb=self.update_orders_cb) # setup the main gui window self._gui.setupMainWindow() self._gui.setUser(self.user_name) # start gps thread self._gps.start() # start ws thread self._ws.start() if gps_rate is None: ## we want gps readings as soon as they arrive self._gps.set_callback(self._ws.send_gps) # start gui thread (tkinter only runs on the main thread :( ) self._gui.loopMainWindow() # < blocking else: ## we want gps readings at a certain rate seconds = 1. / float(gps_rate) while self._gps.has_more_data(): lat, lon, epx, epy, ts = self._gps.get_latest_data() self._ws.send_gps(lat, lon, epx, epy, ts) time.sleep(seconds)
def auto_grade_missing(self, asn_id, verbose=True): if not self.is_authenticate(): raise ClientError('Not authenticated yet!') assignments = self.get_assignments(verbose=False) valid_assignment_ids = [asn['id'] for asn in assignments] if asn_id not in valid_assignment_ids: raise ClientError('Invalid assignment id!') assignments_without_cutoff = [ asn['id'] for asn in assignments if asn['cutoffdate'] == datetime.fromtimestamp(0) ] if asn_id in assignments_without_cutoff: raise ClientError('Assignment without cutoffdate!') assignments_not_cutoff = [ asn['id'] for asn in assignments if asn['cutoffdate'] > datetime.now() ] if asn_id in assignments_not_cutoff: raise ClientError('Assignment submissions not cutoff-ed!') web_service = ws.WS(self.config['domain'], self.config['token']) enrolled_users = self.get_enrolled(verbose=False) user_roles = {user['userid']: user['roles'] for user in enrolled_users} user_names = { user['userid']: "{} {}".format(user['firstname'].capitalize(), user['lastname'].capitalize()) for user in enrolled_users } submissions = { sub['userid']: { 'status': sub['status'], 'gradingstatus': sub['gradingstatus'], } for sub in self.get_submissions(asn_id, verbose=False) } def is_assignment_missing(userid): if 'student' not in user_roles[userid]: return False if userid not in submissions.keys(): return True if submissions[userid]['gradingstatus'] == 'graded': return False if submissions[userid]['status'] == 'new': return True return False student_missing = [ user['userid'] for user in enrolled_users if is_assignment_missing(user['userid']) ] logging.info('--auto-grading--') for st in student_missing: if verbose: print(st, user_names[st], '({})'.format(user_roles[st]), end=' ') if st in submissions.keys(): print(submissions[st]['status'], submissions[st]['gradingstatus']) else: print('') logging.info( f'asn_id={asn_id}, usr_id={st}, user_names={user_names[st]}') web_service.mod_assign_save_grade(asn_id=asn_id, usr_id=st, grade=0, comment=self.config['comment'])