class KalturaBaseTest(unittest.TestCase): """Base class for all Kaltura Tests""" # TODO create a client factory as to avoid thrashing kaltura with logins... def setUp(self): # (client session is enough when we do operations in a users scope) self.config = GetConfig() self.client = KalturaClient(self.config) self.ks = self.client.generateSession(ADMIN_SECRET, USER_NAME, KalturaSessionType.ADMIN, PARTNER_ID, 86400, "") self.client.setKs(self.ks) def tearDown(self): # do cleanup first, probably relies on self.client self.doCleanups() del (self.ks) del (self.client) del (self.config) def readyWait(self, mediaId): """ Block until a 'ready' state is returned from server on the provided mediaId """ sleeptime = 5 while True: print "checking if media id %s is ready" % (mediaId,) mediaEntry = self.client.media.get(mediaId) if mediaEntry.getStatus().getValue() == "2": break else: time.sleep(sleeptime)
class KalturaBaseTest(unittest.TestCase): """Base class for all Kaltura Tests""" #TODO create a client factory as to avoid thrashing kaltura with logins... def setUp(self): #(client session is enough when we do operations in a users scope) self.config = GetConfig() self.client = KalturaClient(self.config) self.ks = self.client.generateSession(ADMIN_SECRET, USER_NAME, KalturaSessionType.ADMIN, PARTNER_ID, 86400, "") self.client.setKs(self.ks) def tearDown(self): #do cleanup first, probably relies on self.client self.doCleanups() del (self.ks) del (self.client) del (self.config) def readyWait(self, mediaId): """ Block until a 'ready' state is returned from server on the provided mediaId """ sleeptime = 5 while True: print "checking if media id %s is ready" % (mediaId, ) mediaEntry = self.client.media.get(mediaId) if mediaEntry.getStatus().getValue() == '2': break else: time.sleep(sleeptime)
def setUp(self): #(client session is enough when we do operations in a users scope) self.config = GetConfig() self.client = KalturaClient(self.config) self.ks = generateSessionFunction(ADMIN_SECRET, USER_NAME, KalturaSessionType.ADMIN, PARTNER_ID, 86400, "") self.client.setKs(self.ks)
def setUp(self): """These tests require that client.session.start be used Instead of self.client.generateSession TODO: Document Why """ self.config = GetConfig() self.client = KalturaClient(self.config) self.ks = None
def kaltura_session(): """ get kaltura_session from user """ kaltura_session = input("Enter ks: ") config = KalturaConfiguration() config.serviceUrl = "https://api.kaltura.nordu.net/" client = KalturaClient(config) client.clientConfiguration["clientTag"] = "change_domain-helper" client.setKs(kaltura_session) return client
def kaltura_session(): """ get ks from user """ ks = input("Enter ks: ") config = KalturaConfiguration() config.serviceUrl = "https://api.kaltura.nordu.net/" client = KalturaClient(config) client.clientConfiguration["clientTag"] = "appToken-helper" client.setKs(ks) return client
def setUp(self): #(client session is enough when we do operations in a users scope) self.config = GetConfig() self.client = KalturaClient(self.config) self.ks = self.client.generateSession(ADMIN_SECRET, USER_NAME, KalturaSessionType.ADMIN, PARTNER_ID, 86400, "") self.client.setKs(self.ks)
def kaltura_client(self): admin_secret = app.config['KALTURA_ADMIN_SECRET'] unique_user_id = app.config['KALTURA_UNIQUE_USER_ID'] partner_id = self.kaltura_partner_id expiry = app.config['KALTURA_EXPIRY'] config = KalturaConfiguration() client = KalturaClient(config) ks = client.session.start( admin_secret, unique_user_id, KalturaSessionType.ADMIN, partner_id, expiry, 'appId:appName-appDomain', ) client.setKs(ks) return client
def app_token_session(self): """ create kaltura session using appToken """ self.statusbar.showMessage("Create kaltura session using appToken") options = QFileDialog.Options() options |= QFileDialog.DontUseNativeDialog filename, _ = QFileDialog.getOpenFileName( self, "QFileDialog.getOpenFileName()", "", "Json Files (*.json)", options=options, ) try: with open(filename) as json_data_file: data = json.load(json_data_file) api_token_id = data["api_token_id"] api_token = data["api_token"] kaltura_partnerid = data["kaltura_partnerid"] kaltura_serviceurl = data["kaltura_serviceurl"] config = KalturaConfiguration(kaltura_partnerid) config.serviceUrl = kaltura_serviceurl self.kaltura_session = KalturaClient(config) user_id = "" widget_id = "_" + str(kaltura_partnerid) expiry = 86400 result = self.kaltura_session.session.startWidgetSession( widget_id, expiry) self.kaltura_session.setKs(result.ks) tokenHash = hashlib.sha256( result.ks.encode("ascii") + api_token.encode("ascii")).hexdigest() type = KalturaSessionType.ADMIN result = self.kaltura_session.appToken.startSession( api_token_id, tokenHash, user_id, type, expiry) self.kaltura_session.setKs(result.ks) MultiDl.session_type = "appToken" except: self.error_dialog.showMessage("Error creating Kaltura session")
def test_MultiRequest(self): """From lines 221- 241 of origional PythonTester.py""" self.client.startMultiRequest() ks = self.client.session.start(ADMIN_SECRET, USER_NAME, KalturaSessionType.ADMIN, PARTNER_ID, 86400, "") self.client.setKs(ks) listResult = self.client.baseEntry.list() multiResult = self.client.doMultiRequest() print(multiResult[1].totalCount) self.client.setKs(multiResult[0]) # error try: mediaEntry = self.client.media.get('invalid entry id') assert (False) except KalturaException as e: assert (e.code == 'ENTRY_ID_NOT_FOUND') # multi request error self.client = KalturaClient(GetConfig()) #start a NEW multirequest (could move to separate unit test?) self.client.startMultiRequest() ks = self.client.session.start(ADMIN_SECRET, USER_NAME, KalturaSessionType.ADMIN, PARTNER_ID, 86400, "") self.client.setKs(ks) mediaEntry = self.client.media.get('invalid entry id') multiResult = self.client.doMultiRequest() self.client.setKs(multiResult[0]) assert (isinstance(multiResult[1], KalturaException)) assert (multiResult[1].code == 'ENTRY_ID_NOT_FOUND') #must be called with existing client multirequest session self._AdvancedMultiRequestExample()
def admin_secret_session(self): """ create kaltura session using adminsecret """ self.statusbar.showMessage("Create kaltura session using adminsecret") kaltura_partnerid, ok = QInputDialog.getText( self, "Input kaltura partnerid", "Input partnerid:") kaltura_adminsecret, ok = QInputDialog.getText(self, "Input adminsecret", "Input adminsecret:") try: config = KalturaConfiguration() config.serviceUrl = "https://api.kaltura.nordu.net/" self.kaltura_session = KalturaClient(config) ks = self.kaltura_session.session.start(kaltura_adminsecret, None, KalturaSessionType.ADMIN, kaltura_partnerid) self.kaltura_session.setKs(ks) MultiDl.session_type = "adminSecret" except: self.error_dialog.showMessage("Error creating Kaltura session")
class KalturaBaseTest(unittest.TestCase): """Base class for all Kaltura Tests""" # TODO create a client factory as to avoid thrashing kaltura with logins... def setUp(self): # (client session is enough when we do operations in a users scope) self.config = GetConfig() self.client = KalturaClient(self.config) self.ks = self.client.generateSession(ADMIN_SECRET, USER_NAME, KalturaSessionType.ADMIN, PARTNER_ID, 86400, "") self.client.setKs(self.ks) def tearDown(self): # do cleanup first, probably relies on self.client self.doCleanups() del (self.ks) del (self.client) del (self.config)
def __init__(self): expiry = app.config['KALTURA_EXPIRY'] partner_id = app.config['KALTURA_PARTNER_ID'] self.client = KalturaClient(KalturaConfiguration()) result = self.client.session.startWidgetSession( expiry=expiry, widgetId=f'_{partner_id}', ) self.client.setKs(result.ks) token_hash = hashlib.sha256( (result.ks + app.config['KALTURA_APP_TOKEN']).encode('ascii')).hexdigest() result = self.client.appToken.startSession( expiry=expiry, id=app.config['KALTURA_APP_TOKEN_ID'], tokenHash=token_hash, type=KalturaSessionType.ADMIN, ) self.client.setKs(result.ks)
class KalturaBaseTest(unittest.TestCase): """Base class for all Kaltura Tests""" #TODO create a client factory as to avoid thrashing kaltura with logins... def setUp(self): #(client session is enough when we do operations in a users scope) self.config = GetConfig() self.client = KalturaClient(self.config) self.ks = generateSessionFunction(ADMIN_SECRET, USER_NAME, KalturaSessionType.ADMIN, PARTNER_ID, 86400, "") self.client.setKs(self.ks) def tearDown(self): #do cleanup first, probably relies on self.client self.doCleanups() del(self.ks) del(self.client) del(self.config)
def _AdvancedMultiRequestExample(self): # this is a separate, local client - not 'self.client' client = KalturaClient( self.config) # matches line 154 in PythonTester.py client.startMultiRequest() from KalturaClient.Plugins.Core import KalturaMixEntry from KalturaClient.Plugins.Core import KalturaEditorType # Request 1 ks = client.session.start(ADMIN_SECRET, USER_NAME, KalturaSessionType.ADMIN, PARTNER_ID, 86400, "") # for the current multi request, the result of the first call will be # used as the ks for next calls client.setKs(ks) mixEntry = KalturaMixEntry() mixEntry.setName(".Net Mix %s" % (testString, )) mixEntry.setEditorType(KalturaEditorType.SIMPLE) # Request 2 mixEntry = client.mixing.add(mixEntry) # Request 3 ulFile = getTestFile('DemoVideo.flv') uploadTokenId = client.media.upload(ulFile) mediaEntry = KalturaMediaEntry() mediaEntry.setName("Media Entry For Mix %s" % (testString, )) mediaEntry.setMediaType(KalturaMediaType.VIDEO) # Request 4 mediaEntry = client.media.addFromUploadedFile(mediaEntry, uploadTokenId) # Request 5 client.mixing.appendMediaEntry(mixEntry.id, mediaEntry.id) response = client.doMultiRequest() for subResponse in response: if isinstance(subResponse, KalturaException): self.fail("Error occurred: " + subResponse.message) # when accessing the response object we will use an index and not the # response number (response number - 1) assert (isinstance(response[1], KalturaMixEntry)) mixEntry = response[1] print("The new mix entry id is: {}".format(mixEntry.id))
def _AdvancedMultiRequestExample(self): # this is a separate, local client - not 'self.client' client = KalturaClient( self.config) # matches line 154 in PythonTester.py client.startMultiRequest() from KalturaClient.Plugins.Core import KalturaMixEntry from KalturaClient.Plugins.Core import KalturaEditorType # Request 1 ks = client.session.start(ADMIN_SECRET, USER_NAME, KalturaSessionType.ADMIN, PARTNER_ID, 86400, "") # for the current multi request, the result of the first call will be # used as the ks for next calls client.setKs(ks) mixEntry = KalturaMixEntry() mixEntry.setName(".Net Mix %s" % (testString,)) mixEntry.setEditorType(KalturaEditorType.SIMPLE) # Request 2 mixEntry = client.mixing.add(mixEntry) # Request 3 ulFile = getTestFile('DemoVideo.flv') uploadTokenId = client.media.upload(ulFile) mediaEntry = KalturaMediaEntry() mediaEntry.setName("Media Entry For Mix %s" % (testString,)) mediaEntry.setMediaType(KalturaMediaType.VIDEO) # Request 4 mediaEntry = client.media.addFromUploadedFile( mediaEntry, uploadTokenId) # Request 5 client.mixing.appendMediaEntry(mixEntry.id, mediaEntry.id) response = client.doMultiRequest() for subResponse in response: if isinstance(subResponse, KalturaException): self.fail("Error occurred: " + subResponse.message) # when accessing the response object we will use an index and not the # response number (response number - 1) assert(isinstance(response[1], KalturaMixEntry)) mixEntry = response[1] print("The new mix entry id is: {}".format(mixEntry.id))
def test_MultiRequest(self): """From lines 221- 241 of origional PythonTester.py""" self.client.startMultiRequest() ks = self.client.session.start(ADMIN_SECRET, USER_NAME, KalturaSessionType.ADMIN, PARTNER_ID, 86400, "") self.client.setKs(ks) listResult = self.client.baseEntry.list() multiResult = self.client.doMultiRequest() print(multiResult[1].totalCount) self.client.setKs(multiResult[0]) # error with self.assertRaises(KalturaException) as cm: mediaEntry = self.client.media.get('invalid entry id') assert(cm.exception.code == 'ENTRY_ID_NOT_FOUND') # multi request error self.client = KalturaClient(GetConfig()) # start a NEW multirequest (could move to separate unit test?) self.client.startMultiRequest() ks = self.client.session.start( ADMIN_SECRET, USER_NAME, KalturaSessionType.ADMIN, PARTNER_ID, 86400, "") self.client.setKs(ks) mediaEntry = self.client.media.get('invalid entry id') multiResult = self.client.doMultiRequest() self.client.setKs(multiResult[0]) assert(isinstance(multiResult[1], KalturaException)) assert(multiResult[1].code == 'ENTRY_ID_NOT_FOUND') # must be called with existing client multirequest session self._AdvancedMultiRequestExample()
def mediaCreation(self) -> DataSourceStatus: """ Update data with Kaltura media metadata from Kaltura API. :return: DataSourceStatus """ self._kalturaInit() KALTURA_MAX_MATCHES_ERROR: str = 'QUERY_EXCEEDED_MAX_MATCHES_ALLOWED' tableName: str = 'mivideo_media_created' logger.info('Starting procedure...') kClient: KalturaRequestConfiguration = KalturaClient(KalturaConfiguration()) kClient.setKs( # pylint: disable=no-member KalturaSessionService(kClient).start( self.kUserSecret, type=KalturaSessionType.ADMIN, partnerId=self.kPartnerId)) kMedia = KalturaMediaService(kClient) lastTime: datetime = self._readTableLastTime( tableName, 'created_at', self.defaultLastTimestamp) createdAtTimestamp: float = lastTime.timestamp() kFilter = KalturaMediaEntryFilter() kFilter.createdAtGreaterThanOrEqual = createdAtTimestamp kFilter.categoriesFullNameIn = self.categoriesFullNameIn kFilter.orderBy = KalturaMediaEntryOrderBy.CREATED_AT_ASC kPager = KalturaFilterPager() kPager.pageSize = 500 # 500 is maximum kPager.pageIndex = 1 results: Sequence[KalturaMediaEntry] = None lastCreatedAtTimestamp: Union[float, int] = createdAtTimestamp lastId: Union[str, None] = None numberResults: int = 0 queryPageNumber: int = kPager.pageIndex # for logging purposes totalNumberResults: int = numberResults # for logging purposes endOfResults = False while not endOfResults: try: results = kMedia.list(kFilter, kPager).objects except KalturaException as kException: if (KALTURA_MAX_MATCHES_ERROR in kException.args): # set new filter timestamp, reset pager to page 1, then continue kFilter.createdAtGreaterThanOrEqual = lastCreatedAtTimestamp logger.debug( f'New filter timestamp: ({kFilter.createdAtGreaterThanOrEqual})') # to avoid dupes, also filter out the last ID returned by previous query # because Kaltura compares createdAt greater than *or equal* to timestamp kFilter.idNotIn = lastId kPager.pageIndex = 1 continue logger.info(f'Other Kaltura API error: "{kException}"') break numberResults = len(results) logger.debug( f'Query page ({queryPageNumber}); number of results: ({numberResults})') if (numberResults > 0): resultDictionaries: Sequence[Dict] = tuple(r.__dict__ for r in results) creationData: pd.DataFrame = self._makeCreationData(resultDictionaries) creationData.to_sql( tableName, self.appDb.engine, if_exists='append', index=False) courseData: pd.DataFrame = self._makeCourseData(resultDictionaries) courseData.to_sql('mivideo_media_courses', self.appDb.engine, if_exists='append', index=False, method=self._queryRunner) lastCreatedAtTimestamp = results[-1].createdAt lastId = results[-1].id totalNumberResults += numberResults endOfResults = (numberResults < kPager.pageSize) kPager.pageIndex += 1 queryPageNumber += 1 logger.info(f'Total number of results: ({totalNumberResults})') logger.info('Procedure complete.') return DataSourceStatus(ValidDataSourceName.KALTURA_API)
class MultiDl(QMainWindow): session_type = "" def __init__(self): super(MultiDl, self).__init__() self.threadpool = QThreadPool() self.threadpool.setMaxThreadCount(5) self.initUI() def app_token_session(self): """ create kaltura session using appToken """ self.statusbar.showMessage("Create kaltura session using appToken") options = QFileDialog.Options() options |= QFileDialog.DontUseNativeDialog filename, _ = QFileDialog.getOpenFileName( self, "QFileDialog.getOpenFileName()", "", "Json Files (*.json)", options=options, ) try: with open(filename) as json_data_file: data = json.load(json_data_file) api_token_id = data["api_token_id"] api_token = data["api_token"] kaltura_partnerid = data["kaltura_partnerid"] kaltura_serviceurl = data["kaltura_serviceurl"] config = KalturaConfiguration(kaltura_partnerid) config.serviceUrl = kaltura_serviceurl self.kaltura_session = KalturaClient(config) user_id = "" widget_id = "_" + str(kaltura_partnerid) expiry = 86400 result = self.kaltura_session.session.startWidgetSession( widget_id, expiry) self.kaltura_session.setKs(result.ks) tokenHash = hashlib.sha256( result.ks.encode("ascii") + api_token.encode("ascii")).hexdigest() type = KalturaSessionType.ADMIN result = self.kaltura_session.appToken.startSession( api_token_id, tokenHash, user_id, type, expiry) self.kaltura_session.setKs(result.ks) MultiDl.session_type = "appToken" except: self.error_dialog.showMessage("Error creating Kaltura session") def admin_secret_session(self): """ create kaltura session using adminsecret """ self.statusbar.showMessage("Create kaltura session using adminsecret") kaltura_partnerid, ok = QInputDialog.getText( self, "Input kaltura partnerid", "Input partnerid:") kaltura_adminsecret, ok = QInputDialog.getText(self, "Input adminsecret", "Input adminsecret:") try: config = KalturaConfiguration() config.serviceUrl = "https://api.kaltura.nordu.net/" self.kaltura_session = KalturaClient(config) ks = self.kaltura_session.session.start(kaltura_adminsecret, None, KalturaSessionType.ADMIN, kaltura_partnerid) self.kaltura_session.setKs(ks) MultiDl.session_type = "adminSecret" except: self.error_dialog.showMessage("Error creating Kaltura session") def download_entry_id(self): """ Download videofiles from entryId """ files_to_download = {} parent_entry_id, ok = QInputDialog.getText(self, "Input entryid", "Input entryid:") self.statusbar.showMessage("Download files for parent entryId " + parent_entry_id) self.top_label.setText("Downloading files for parent entryId " + parent_entry_id) files_to_download.update({ parent_entry_id: self.kaltura_session.media.get(parent_entry_id).downloadUrl }) filter = KalturaMediaEntryFilter() filter.parentEntryIdEqual = parent_entry_id pager = KalturaFilterPager() child_entries = self.kaltura_session.media.list(filter, pager) for child in child_entries.objects: files_to_download.update({child.id: child.downloadUrl}) self.thread_download(parent_entry_id, files_to_download) def initUI(self): """ user interface """ self.setGeometry(200, 200, 400, 400) self.setWindowTitle("multidl") self.display = QLabel(self) self.display.move(50, 50) self.statusbar = QStatusBar() self.setStatusBar(self.statusbar) # file menu self.statusbar.showMessage("Choose an option from the filemenu") exit_act = QAction("Exit", self) exit_act.setStatusTip("Exit application") exit_act.triggered.connect(qApp.quit) app_token_act = QAction("Load apptoken config", self) app_token_act.setStatusTip("Load apptoken config") app_token_act.triggered.connect(self.app_token_session) admin_secret_act = QAction("Start adminsecret session", self) admin_secret_act.setStatusTip("Start adminsecret session") admin_secret_act.triggered.connect(self.admin_secret_session) entry_id_act = QAction("Download multistream", self) entry_id_act.setStatusTip("Download multistream") entry_id_act.triggered.connect(self.download_entry_id) menubar = self.menuBar() file_menu = menubar.addMenu("&File") file_menu.addAction(app_token_act) file_menu.addAction(admin_secret_act) file_menu.addAction(entry_id_act) file_menu.addAction(exit_act) # Layout self.main_widget = QWidget() self.setCentralWidget(self.main_widget) self.top_label = QLabel("Choose an option from the filemenu") self.error_dialog = QErrorMessage() self.download_label_1 = QLabel() self.download_label_2 = QLabel() self.download_label_3 = QLabel() self.download_label_4 = QLabel() self.progress_bar_1 = QProgressBar() self.progress_bar_1.hide() self.progress_bar_2 = QProgressBar() self.progress_bar_2.hide() self.progress_bar_3 = QProgressBar() self.progress_bar_3.hide() self.progress_bar_4 = QProgressBar() self.progress_bar_4.hide() self.layout = QFormLayout(self.main_widget) self.layout.addRow(self.top_label) self.layout.addRow(self.download_label_1, self.progress_bar_1) self.layout.addRow(self.download_label_2, self.progress_bar_2) self.layout.addRow(self.download_label_3, self.progress_bar_3) self.layout.addRow(self.download_label_4, self.progress_bar_4) self.show() def thread_download(self, parent_entryid, files_to_download): """ start worker threads for downloading files """ count = 1 for entryid, download_url in files_to_download.items(): save_loc = parent_entryid + "-" + entryid + ".mp4" if count == 1: worker = Worker(urllib.request.urlretrieve, download_url, save_loc, self.callback_1) self.progress_bar_1.show() self.download_label_1.setText("Downloading " + entryid) worker.signals.finished.connect(self.thread_1_complete) if count == 2: worker = Worker(urllib.request.urlretrieve, download_url, save_loc, self.callback_2) self.progress_bar_2.show() self.download_label_2.setText("Downloading " + entryid) worker.signals.finished.connect(self.thread_2_complete) if count == 3: worker = Worker(urllib.request.urlretrieve, download_url, save_loc, self.callback_3) self.progress_bar_3.show() self.download_label_3.setText("Downloading " + entryid) worker.signals.finished.connect(self.thread_3_complete) if count == 4: worker = Worker(urllib.request.urlretrieve, download_url, save_loc, self.callback_4) self.progress_bar_4.show() self.download_label_4.setText("Downloading " + entryid) worker.signals.finished.connect(self.thread_4_complete) self.threadpool.start(worker) count += 1 def callback_1(self, progress, blocksize, totalsize): """ callback for progress bar download 1 """ data_read = progress * blocksize if totalsize > 0: download_percentage = data_read * 100 / totalsize self.progress_bar_1.setValue(int(download_percentage)) def callback_2(self, progress, blocksize, totalsize): """ callback for progress bar download 2 """ data_read = progress * blocksize if totalsize > 0: download_percentage = data_read * 100 / totalsize self.progress_bar_2.setValue(int(download_percentage)) def callback_3(self, progress, blocksize, totalsize): """ callback for progress bar download 3 """ data_read = progress * blocksize if totalsize > 0: download_percentage = data_read * 100 / totalsize self.progress_bar_3.setValue(int(download_percentage)) def callback_4(self, progress, blocksize, totalsize): """ callback for progress bar download 4 """ data_read = progress * blocksize if totalsize > 0: download_percentage = data_read * 100 / totalsize self.progress_bar_4.setValue(int(download_percentage)) def thread_1_complete(self): """ self explanatory! """ self.download_label_1.setText("Download complete!") self.progress_bar_1.hide() def thread_2_complete(self): """ self explanatory! """ self.download_label_2.setText("Download complete!") self.progress_bar_2.hide() def thread_3_complete(self): """ self explanatory! """ self.download_label_3.setText("Download complete!") self.progress_bar_3.hide() def thread_4_complete(self): """ self explanatory! """ self.download_label_4.setText("Download complete!") self.progress_bar_4.hide()
class MultiRequestTests(KalturaBaseTest): def setUp(self): """These tests require that client.session.start be used Instead of self.client.generateSession TODO: Document Why """ self.config = GetConfig() self.client = KalturaClient(self.config) self.ks = None def test_MultiRequest(self): """From lines 221- 241 of origional PythonTester.py""" self.client.startMultiRequest() ks = self.client.session.start(ADMIN_SECRET, USER_NAME, KalturaSessionType.ADMIN, PARTNER_ID, 86400, "") self.client.setKs(ks) listResult = self.client.baseEntry.list() multiResult = self.client.doMultiRequest() print(multiResult[1].totalCount) self.client.setKs(multiResult[0]) # error with self.assertRaises(KalturaException) as cm: mediaEntry = self.client.media.get('invalid entry id') assert (cm.exception.code == 'ENTRY_ID_NOT_FOUND') # multi request error self.client = KalturaClient(GetConfig()) # start a NEW multirequest (could move to separate unit test?) self.client.startMultiRequest() ks = self.client.session.start(ADMIN_SECRET, USER_NAME, KalturaSessionType.ADMIN, PARTNER_ID, 86400, "") self.client.setKs(ks) mediaEntry = self.client.media.get('invalid entry id') multiResult = self.client.doMultiRequest() self.client.setKs(multiResult[0]) assert (isinstance(multiResult[1], KalturaException)) assert (multiResult[1].code == 'ENTRY_ID_NOT_FOUND') # must be called with existing client multirequest session self._AdvancedMultiRequestExample() # copied from C# tester def _AdvancedMultiRequestExample(self): # this is a separate, local client - not 'self.client' client = KalturaClient( self.config) # matches line 154 in PythonTester.py client.startMultiRequest() from KalturaClient.Plugins.Core import KalturaMixEntry from KalturaClient.Plugins.Core import KalturaEditorType # Request 1 ks = client.session.start(ADMIN_SECRET, USER_NAME, KalturaSessionType.ADMIN, PARTNER_ID, 86400, "") # for the current multi request, the result of the first call will be # used as the ks for next calls client.setKs(ks) mixEntry = KalturaMixEntry() mixEntry.setName(".Net Mix %s" % (testString, )) mixEntry.setEditorType(KalturaEditorType.SIMPLE) # Request 2 mixEntry = client.mixing.add(mixEntry) # Request 3 ulFile = getTestFile('DemoVideo.flv') uploadTokenId = client.media.upload(ulFile) mediaEntry = KalturaMediaEntry() mediaEntry.setName("Media Entry For Mix %s" % (testString, )) mediaEntry.setMediaType(KalturaMediaType.VIDEO) # Request 4 mediaEntry = client.media.addFromUploadedFile(mediaEntry, uploadTokenId) # Request 5 client.mixing.appendMediaEntry(mixEntry.id, mediaEntry.id) response = client.doMultiRequest() for subResponse in response: if isinstance(subResponse, KalturaException): self.fail("Error occurred: " + subResponse.message) # when accessing the response object we will use an index and not the # response number (response number - 1) assert (isinstance(response[1], KalturaMixEntry)) mixEntry = response[1] print("The new mix entry id is: {}".format(mixEntry.id))
parser = argparse.ArgumentParser(description="Helper for kaltura sessions") group = parser.add_mutually_exclusive_group(required=True) group.add_argument("-s", "--start", help="start session", action="store_true") group.add_argument("-e", "--end", help="end session", action="store_true") group.add_argument("-g", "--get", help="get session", action="store_true") parser.add_argument("-c", "--client-tag", help="client tag", metavar="client-tag") args = parser.parse_args() if args.start: partnerId = input("Enter partnerId: ") adminSecret = input("Enter adminSecret: ") conf = KalturaConfiguration() conf.serviceUrl = "https://api.kaltura.nordu.net" kc = KalturaClient(conf) kc.clientConfiguration["clientTag"] = args.client_tag ks = kc.session.start(adminSecret, None, 2, partnerId) print("New kalturaSession: " + ks) elif args.get: kalturaSession = input("Enter kalturaSession: ") conf = KalturaConfiguration() conf.serviceUrl = "https://api.kaltura.nordu.net" kc = KalturaClient(conf) kc.setKs(kalturaSession) try: ks = kc.session.get(kalturaSession) print("\nkalturaSession:") print("sessionType: " + str(ks.sessionType.value)) print("partnerId: " + str(ks.partnerId)) if ks.userId:
class Kaltura: @skip_when_pytest() def __init__(self): expiry = app.config['KALTURA_EXPIRY'] partner_id = app.config['KALTURA_PARTNER_ID'] self.client = KalturaClient(KalturaConfiguration()) result = self.client.session.startWidgetSession( expiry=expiry, widgetId=f'_{partner_id}', ) self.client.setKs(result.ks) token_hash = hashlib.sha256( (result.ks + app.config['KALTURA_APP_TOKEN']).encode('ascii')).hexdigest() result = self.client.appToken.startSession( expiry=expiry, id=app.config['KALTURA_APP_TOKEN_ID'], tokenHash=token_hash, type=KalturaSessionType.ADMIN, ) self.client.setKs(result.ks) @skip_when_pytest() def add_to_kaltura_category(self, category_id, entry_id): category_entry_user_id = 'RecordScheduleGroup' # TODO: Does this need to be be configurable? Probably. category_entry = KalturaCategoryEntry( categoryId=category_id, entryId=entry_id, status=KalturaCategoryEntryStatus.ACTIVE, creatorUserId=category_entry_user_id, ) self.client.categoryEntry.add(category_entry) @skip_when_pytest() def get_base_entry(self, entry_id): entry = self.client.baseEntry.get(entryId=entry_id) if entry: return { 'createdAt': entry.createdAt, 'creatorId': entry.creatorId, 'description': entry.description, 'displayInSearch': entry.displayInSearch, 'entitledUsersEdit': entry.entitledUsersEdit, 'entitledUsersPublish': entry.entitledUsersPublish, 'entitledUsersView': entry.entitledUsersView, 'id': entry.id, 'name': entry.name, 'partnerId': entry.partnerId, 'status': entry.status, 'tags': entry.tags, 'updatedAt': entry.updatedAt, 'userId': entry.userId, } else: return None @skip_when_pytest() def get_categories(self, template_entry_id): category_entries = self._get_category_entries( KalturaCategoryEntryFilter(entryIdEqual=template_entry_id)) if category_entries: category_ids = [entry['categoryId'] for entry in category_entries] category_filter = KalturaCategoryFilter(idIn=','.join( str(id_) for id_ in category_ids)) return self._get_categories( kaltura_category_filter=category_filter) else: return [] @skip_when_pytest() def get_events_by_location(self, kaltura_resource_id): event_filter = KalturaScheduleEventFilter( orderBy='-startDate', resourceIdEqual=str(kaltura_resource_id), ) return self._get_events(kaltura_event_filter=event_filter) @skip_when_pytest() def get_events_by_tag(self, tags_like=CREATED_BY_DIABLO_TAG): return self._get_events( kaltura_event_filter=KalturaScheduleEventFilter( tagsLike=tags_like)) @skip_when_pytest() def get_event(self, event_id): events = self._get_events( kaltura_event_filter=KalturaScheduleEventFilter(idEqual=event_id)) return events[0] if events else None @skip_when_pytest() def get_events_in_date_range(self, end_date, start_date): event_filter = KalturaRecordScheduleEventFilter( endDateLessThanOrEqual=int(end_date.timestamp()), startDateGreaterThanOrEqual=int(start_date.timestamp()), ) return self._get_events(kaltura_event_filter=event_filter) @cachify('kaltura/schedule_resources', timeout=30) def get_schedule_resources(self): def _fetch(page_index): return self.client.schedule.scheduleResource.list( filter=KalturaScheduleResourceFilter(), pager=KalturaFilterPager(pageIndex=page_index, pageSize=DEFAULT_KALTURA_PAGE_SIZE), ) return [{ 'id': o.id, 'name': o.name } for o in _get_kaltura_objects(_fetch)] @skip_when_pytest() def get_canvas_category_object(self, canvas_course_site_id): return self.get_category_object( name=f'Canvas>site>channels>{canvas_course_site_id}') @skip_when_pytest() def get_category_object(self, name): response = self.client.category.list( filter=KalturaCategoryFilter(fullNameEqual=name), pager=KalturaFilterPager(pageIndex=1, pageSize=1), ) category_objects = [ _category_object_to_json(o) for o in response.objects ] return category_objects[0] if category_objects else None @skip_when_pytest(mock_object=int(datetime.now().timestamp())) def schedule_recording( self, canvas_course_site_ids, course_label, instructors, meeting, publish_type, recording_type, room, term_id, ): category_ids = [] common_category = self.get_category_object( name=app.config['KALTURA_COMMON_CATEGORY']) if common_category: category_ids.append(common_category['id']) if publish_type == 'kaltura_media_gallery': for canvas_course_site_id in canvas_course_site_ids: category = self.get_canvas_category_object( canvas_course_site_id=canvas_course_site_id) if category: category_ids.append(category['id']) kaltura_schedule = self._schedule_recurring_events_in_kaltura( category_ids=category_ids, course_label=course_label, instructors=instructors, meeting=meeting, publish_type=publish_type, recording_type=recording_type, room=room, term_id=term_id, ) recurrences_filter = KalturaScheduleEventFilter( parentIdEqual=kaltura_schedule.id) for recurrence in self._get_events( kaltura_event_filter=recurrences_filter): if recurrence['blackoutConflicts']: self.client.schedule.scheduleEvent.cancel(recurrence['id']) app.logger.warn(f""" {course_label}: Event {recurrence['id']}), a child of Kaltura series {kaltura_schedule.id}, cancelled due to blackout conflict(s): {recurrence['blackoutConflicts']} """) # Link the schedule to the room (ie, capture agent) self._attach_scheduled_recordings_to_room( kaltura_schedule=kaltura_schedule, room=room) return kaltura_schedule.id @skip_when_pytest() def delete(self, event_id): def is_future(kaltura_event): start_date = dateutil.parser.parse(kaltura_event['startDate']) return start_date.timestamp() > datetime.now().timestamp() event = self.get_event(event_id) if event: recurrence_type = event['recurrenceType'] if recurrence_type == 'Recurring': # This is a Kaltura series event. if is_future(kaltura_event=event): # Start date of the series in the future. Delete it all. self.client.schedule.scheduleEvent.delete(event_id) else: # Series started in the past. Delete only the future 'recurrences'. recurrences_filter = KalturaScheduleEventFilter( parentIdEqual=event_id) for recurrence in self._get_events( kaltura_event_filter=recurrences_filter): if is_future(kaltura_event=recurrence): self.client.schedule.scheduleEvent.cancel( recurrence['id']) elif recurrence_type == 'Recurrence': # Delete is not supported for "recurrence" events. self.client.schedule.scheduleEvent.cancel(event_id) else: # This is not a series event. Delete it, whatever it is. self.client.schedule.scheduleEvent.delete(event_id) def ping(self): filter_ = KalturaMediaEntryFilter() filter_.nameLike = "Love is the drug I'm thinking of" result = self.client.baseEntry.list( filter=filter_, pager=KalturaFilterPager(pageSize=1), ) return result.totalCount is not None def update_base_entry(self, entitled_users, entry_id): self.client.baseEntry.update( entryId=entry_id, baseEntry=KalturaBaseEntry(entitledUsersEdit=','.join( _to_normalized_set(entitled_users))), ) def _get_events(self, kaltura_event_filter): def _fetch(page_index): return self.client.schedule.scheduleEvent.list( filter=kaltura_event_filter, pager=KalturaFilterPager(pageIndex=page_index, pageSize=DEFAULT_KALTURA_PAGE_SIZE), ) return _events_to_api_json(_get_kaltura_objects(_fetch)) def _get_categories(self, kaltura_category_filter): def _fetch(page_index): return self.client.category.list( filter=kaltura_category_filter, pager=KalturaFilterPager(pageIndex=page_index, pageSize=DEFAULT_KALTURA_PAGE_SIZE), ) return [ _category_object_to_json(obj) for obj in _get_kaltura_objects(_fetch) ] def _get_category_entries(self, kaltura_category_entry_filter): def _fetch(page_index): return self.client.categoryEntry.list( filter=kaltura_category_entry_filter, pager=KalturaFilterPager(pageIndex=page_index, pageSize=DEFAULT_KALTURA_PAGE_SIZE), ) return [ _category_entry_object_to_json(obj) for obj in _get_kaltura_objects(_fetch) ] def _schedule_recurring_events_in_kaltura( self, category_ids, course_label, instructors, meeting, publish_type, recording_type, room, term_id, ): # Recording starts X minutes before/after official start; it ends Y minutes before/after official end time. days = format_days(meeting['days']) start_time = _adjust_time(meeting['startTime'], app.config['KALTURA_RECORDING_OFFSET_START']) end_time = _adjust_time(meeting['endTime'], app.config['KALTURA_RECORDING_OFFSET_END']) app.logger.info(f""" Prepare to schedule recordings for {course_label}: Room: {room.location} Instructor UIDs: {[instructor['uid'] for instructor in instructors]} Schedule: {days}, {start_time} to {end_time} Recording: {recording_type}; {publish_type} """) term_name = term_name_for_sis_id(term_id) recording_start_date = get_recording_start_date( meeting, return_today_if_past_start=True) recording_end_date = get_recording_end_date(meeting) summary = f'{course_label} ({term_name})' app.logger.info(f""" {course_label} ({term_name}) meets in {room.location}, between {start_time.strftime('%H:%M')} and {end_time.strftime('%H:%M')}, on {days}. Recordings of type {recording_type} will be published to {publish_type}. """) first_day_start = get_first_matching_datetime_of_term( meeting_days=days, start_date=recording_start_date, time_hours=start_time.hour, time_minutes=start_time.minute, ) first_day_end = get_first_matching_datetime_of_term( meeting_days=days, start_date=recording_start_date, time_hours=end_time.hour, time_minutes=end_time.minute, ) description = get_series_description(course_label, instructors, term_name) base_entry = self._create_kaltura_base_entry( description=description, instructors=instructors, name=f'{summary} in {room.location}', ) for category_id in category_ids or []: self.add_to_kaltura_category(category_id=category_id, entry_id=base_entry.id) until = datetime.combine( recording_end_date, time(end_time.hour, end_time.minute), tzinfo=default_timezone(), ) recurring_event = KalturaRecordScheduleEvent( # https://developer.kaltura.com/api-docs/General_Objects/Objects/KalturaScheduleEvent classificationType=KalturaScheduleEventClassificationType. PUBLIC_EVENT, comment=f'{summary} in {room.location}', contact=','.join(instructor['uid'] for instructor in instructors), description=description, duration=(end_time - start_time).seconds, endDate=first_day_end.timestamp(), organizer=app.config['KALTURA_EVENT_ORGANIZER'], ownerId=app.config['KALTURA_KMS_OWNER_ID'], partnerId=app.config['KALTURA_PARTNER_ID'], recurrence=KalturaScheduleEventRecurrence( # https://developer.kaltura.com/api-docs/General_Objects/Objects/KalturaScheduleEventRecurrence byDay=','.join(days), frequency=KalturaScheduleEventRecurrenceFrequency.WEEKLY, # 'interval' is not documented. When scheduling manually, the value was 1 in each individual event. interval=1, name=summary, timeZone='US/Pacific', until=until.timestamp(), weekStartDay=days[0], ), recurrenceType=KalturaScheduleEventRecurrenceType.RECURRING, startDate=first_day_start.timestamp(), status=KalturaScheduleEventStatus.ACTIVE, summary=summary, tags=CREATED_BY_DIABLO_TAG, templateEntryId=base_entry.id, ) return self.client.schedule.scheduleEvent.add(recurring_event) def _create_kaltura_base_entry( self, description, name, instructors, ): instructor_uids = [instructor['uid'] for instructor in instructors] uids = ','.join( _to_normalized_set(instructor_uids)) if instructor_uids else None base_entry = KalturaBaseEntry( description=description, displayInSearch=KalturaEntryDisplayInSearchType.PARTNER_ONLY, entitledUsersEdit=uids, entitledUsersPublish=uids, moderationStatus=KalturaEntryModerationStatus.AUTO_APPROVED, name=name, partnerId=app.config['KALTURA_PARTNER_ID'], status=KalturaEntryStatus.NO_CONTENT, tags=CREATED_BY_DIABLO_TAG, type=KalturaEntryType.MEDIA_CLIP, userId='RecordScheduleGroup', ) return self.client.baseEntry.add(base_entry) def _attach_scheduled_recordings_to_room(self, kaltura_schedule, room): utc_now_timestamp = int(datetime.utcnow().timestamp()) event_resource = self.client.schedule.scheduleEventResource.add( KalturaScheduleEventResource( eventId=kaltura_schedule.id, resourceId=room.kaltura_resource_id, partnerId=app.config['KALTURA_PARTNER_ID'], createdAt=utc_now_timestamp, updatedAt=utc_now_timestamp, ), ) app.logger.info( f'Kaltura schedule {kaltura_schedule.id} attached to {room.location}: {event_resource}' )
class MultiRequestTests(KalturaBaseTest): def setUp(self): """These tests require that client.session.start be used Instead of self.client.generateSession TODO: Document Why """ self.config = GetConfig() self.client = KalturaClient(self.config) self.ks = None def test_MultiRequest(self): """From lines 221- 241 of origional PythonTester.py""" self.client.startMultiRequest() ks = self.client.session.start(ADMIN_SECRET, USER_NAME, KalturaSessionType.ADMIN, PARTNER_ID, 86400, "") self.client.setKs(ks) listResult = self.client.baseEntry.list() multiResult = self.client.doMultiRequest() print(multiResult[1].totalCount) self.client.setKs(multiResult[0]) # error with self.assertRaises(KalturaException) as cm: mediaEntry = self.client.media.get('invalid entry id') assert(cm.exception.code == 'ENTRY_ID_NOT_FOUND') # multi request error self.client = KalturaClient(GetConfig()) # start a NEW multirequest (could move to separate unit test?) self.client.startMultiRequest() ks = self.client.session.start( ADMIN_SECRET, USER_NAME, KalturaSessionType.ADMIN, PARTNER_ID, 86400, "") self.client.setKs(ks) mediaEntry = self.client.media.get('invalid entry id') multiResult = self.client.doMultiRequest() self.client.setKs(multiResult[0]) assert(isinstance(multiResult[1], KalturaException)) assert(multiResult[1].code == 'ENTRY_ID_NOT_FOUND') # must be called with existing client multirequest session self._AdvancedMultiRequestExample() # copied from C# tester def _AdvancedMultiRequestExample(self): # this is a separate, local client - not 'self.client' client = KalturaClient( self.config) # matches line 154 in PythonTester.py client.startMultiRequest() from KalturaClient.Plugins.Core import KalturaMixEntry from KalturaClient.Plugins.Core import KalturaEditorType # Request 1 ks = client.session.start(ADMIN_SECRET, USER_NAME, KalturaSessionType.ADMIN, PARTNER_ID, 86400, "") # for the current multi request, the result of the first call will be # used as the ks for next calls client.setKs(ks) mixEntry = KalturaMixEntry() mixEntry.setName(".Net Mix %s" % (testString,)) mixEntry.setEditorType(KalturaEditorType.SIMPLE) # Request 2 mixEntry = client.mixing.add(mixEntry) # Request 3 ulFile = getTestFile('DemoVideo.flv') uploadTokenId = client.media.upload(ulFile) mediaEntry = KalturaMediaEntry() mediaEntry.setName("Media Entry For Mix %s" % (testString,)) mediaEntry.setMediaType(KalturaMediaType.VIDEO) # Request 4 mediaEntry = client.media.addFromUploadedFile( mediaEntry, uploadTokenId) # Request 5 client.mixing.appendMediaEntry(mixEntry.id, mediaEntry.id) response = client.doMultiRequest() for subResponse in response: if isinstance(subResponse, KalturaException): self.fail("Error occurred: " + subResponse.message) # when accessing the response object we will use an index and not the # response number (response number - 1) assert(isinstance(response[1], KalturaMixEntry)) mixEntry = response[1] print("The new mix entry id is: {}".format(mixEntry.id))