diff --git a/bbcli/cli.py b/bbcli/cli.py index 372ba90f68de95a4b7af8a76f6bbd46eb0bb283a..1bba8d8e6f225b07f092ff3e7e9248fb1d6a32e2 100644 --- a/bbcli/cli.py +++ b/bbcli/cli.py @@ -50,17 +50,17 @@ LOGIN AND LOGOUT COMMANDS @click.command(name='login') def authorize_user(): """ - Authorize user with username and password. + Authorize user with username and password """ login() @click.command(name='logout') def logout(): """ - Logout user. + Logout user """ open(f'{os.path.dirname(os.path.abspath(__file__))}/.env', 'w').close() - click.echo('Sucessfully logged out.') + click.echo('Sucessfully logged out') entry_point.add_command(authorize_user) entry_point.add_command(logout) @@ -68,7 +68,7 @@ entry_point.add_command(logout) """ SHELL COMPLETION COMMANDS """ -@click.command(name='activate-shell-completion', help='Activate shell completion for your shell') +@click.command(name='activate-shell-completion', help='Activate shell completion') @click.argument('shell', required=True, type=str) def activate_shell_completion(shell: str): if shell == 'fish': @@ -87,11 +87,11 @@ def activate_shell_completion(shell: str): shutil.copy(f'{os.path.dirname(os.path.abspath(__file__))}/shell-completion/.bb-complete.bash', os.path.expanduser('~')) with open(os.path.join(os.path.expanduser('~'), f'.{shell}rc'), 'a') as f: f.write('\n. ~/.bb-complete.bash\n') - click.echo('Shell completion activated! Restart shell to load the changes.') + click.echo('Shell completion activated. Restart shell to load changes') else: - click.echo('Shell completion already activated.') + click.echo('Shell completion already activated') else: - click.echo('Did not recognize the Shell or CLI shell completion is not compatible with your Shell.') + click.echo('Shell not recognized, or CLI shell completion is not compatible with your Shell') entry_point.add_command(activate_shell_completion) @@ -141,7 +141,7 @@ announcements.add_command(update_announcement) @click.pass_context def assignments(ctx): """ - Commands for creating, listing and submitting assignments. + Commands for creating, listing and submitting assignments """ authenticate_user() load_dotenv() @@ -157,7 +157,7 @@ assignments.add_command(grade_assignment) @click.pass_context def attempts(ctx): """ - Commands for creating, submitting and listing attempts for an assignment. + Commands for creating, submitting and listing attempts for an assignment """ pass diff --git a/bbcli/commands/announcements.py b/bbcli/commands/announcements.py index 60774d1e5454f05ada3262addf4f8177055c5402..8921fa07a06a8f44424236c55d4bbb19eb4bb2ad 100644 --- a/bbcli/commands/announcements.py +++ b/bbcli/commands/announcements.py @@ -7,12 +7,13 @@ from bbcli.utils.utils import format_date from bbcli.views import announcement_view import os + @click.command(name='list', help='This command lists your announcements.\nEither all announcements, all announcements from a spesific course, or one announcement.') @click.option('-c', '--course', 'course_id', required=False, type=str, help='COURSE ID, list announcements from a spesific course') @click.option('-a', '--announcement', 'announcement_id', required=False, type=str, help='ANNONUCEMENT ID, list a spesific announcement from a course.') @click.pass_context @list_exception_handler -def list_announcements(ctx,course_id=None, announcement_id=None): +def list_announcements(ctx, course_id=None, announcement_id=None): response = None if announcement_id: @@ -56,7 +57,8 @@ def create_announcement(ctx, course_id: str, title: str, start_date: str, end_da @click.pass_context @delete_exception_handler def delete_announcement(ctx, course_id: str, announcement_id: str): - announcements_service.delete_announcement(ctx.obj['SESSION'], course_id, announcement_id) + announcements_service.delete_announcement( + ctx.obj['SESSION'], course_id, announcement_id) announcement_view.print_announcement_deleted() @@ -66,5 +68,6 @@ def delete_announcement(ctx, course_id: str, announcement_id: str): @click.pass_context @update_exception_handler def update_announcement(ctx, course_id: str, announcement_id: str): - response = announcements_service.update_announcement(ctx.obj['SESSION'], course_id, announcement_id) + response = announcements_service.update_announcement( + ctx.obj['SESSION'], course_id, announcement_id) announcement_view.print_announcement_updated(response) diff --git a/bbcli/commands/assignments.py b/bbcli/commands/assignments.py index 3937670bdbfc6bf23d797655b1c26294db343037..7421099600524c16916a5b3ac1578c2d508ba774 100644 --- a/bbcli/commands/assignments.py +++ b/bbcli/commands/assignments.py @@ -24,7 +24,7 @@ def attempt_options(function): # TODO: This function is a copy of the same function in contents.py. Fix this. @click.command(name='create', help='Create an assignment.') -@click.option('-c', '--course' ,'course_id', required=True, help='COURSE ID, of the course you want to create an assignment in.') +@click.option('-c', '--course', 'course_id', required=True, help='COURSE ID, of the course you want to create an assignment in.') @click.option('-f', '--folder', 'parent_id', required=True, type=str, help='FOLDER ID, of the folder you want to place the assignment.') @click.argument('title', required=True, type=str) @click.argument('attachments', required=False, nargs=-1, type=click.Path()) @@ -58,7 +58,7 @@ def get_assignments(ctx, course_id): @click.command(name='list', help='List attempts for an assignment.') -@click.option('-c', '--course' ,'course_id', required=True, help='COURSE ID, of the course you want the assignment attempts from') +@click.option('-c', '--course', 'course_id', required=True, help='COURSE ID, of the course you want the assignment attempts from') @click.option('-a', '--assignment', 'column_id', required=True, help='ASSIGNMENT ID, of the assignment you want attempts from') @click.option('--submitted', is_flag=True, help='List only submitted attempts.') @click.pass_context @@ -70,7 +70,7 @@ def get_attempts(ctx, course_id, column_id, submitted): # TODO: Retrieve the submission w/ attachments. @click.command(name='get', help='Get a specific attempt for an assignment.') -@click.option('-c', '--course' ,'course_id', required=True, help='COURSE ID, of the course of you want to get attempt from') +@click.option('-c', '--course', 'course_id', required=True, help='COURSE ID, of the course of you want to get attempt from') @click.option('-a', '--assignment', 'column_id', required=True, help='ASSIGNMENT ID, of the assignment you want attempts from') @click.option('-at', '--attempt', 'attempt_id', required=True, help='ATTEMPT ID, of the attempt you want to fetch.') @click.pass_context @@ -81,7 +81,7 @@ def get_attempt(ctx, course_id, column_id, attempt_id): @click.command(name='submit', help='Submit assignment attempt.') -@click.option('-c', '--course' ,'course_id', required=True, help='COURSE ID, of the course to submit an assignment to.') +@click.option('-c', '--course', 'course_id', required=True, help='COURSE ID, of the course to submit an assignment to.') @click.option('-a', '--assignment', 'column_id', required=True, help='ASSIGNMENT ID, of the assignment you want to submit to.') @click.option('--studentComments', help='The student comments associated with this attempt.') @click.option('--studentSubmission', help='The student submission text associated with this attempt.') @@ -95,7 +95,7 @@ def submit_attempt(ctx, course_id, column_id, studentComments, studentSubmission @click.command(name='submit-draft', help='Submit assignment draft.') -@click.option('-c', '--course' ,'course_id', required=True, help='COURSE ID, of the course where the assignment is.') +@click.option('-c', '--course', 'course_id', required=True, help='COURSE ID, of the course where the assignment is.') @click.option('-a', '--assignment', 'column_id', required=True, help='ASSIGNMENT ID, of the assignment you want to submit to.') @click.option('-at', '--attempt', 'attempt_id', required=True, help='ATTEMPT ID, of the attempt you want to update.') @click.pass_context @@ -106,7 +106,7 @@ def submit_draft(ctx, course_id, column_id, attempt_id): @click.command(name='update', help='Update assignment.') -@click.option('-c', '--course' ,'course_id', required=True, help='COURSE ID, of the course where the assignment is.') +@click.option('-c', '--course', 'course_id', required=True, help='COURSE ID, of the course where the assignment is.') @click.option('-a', '--assignment', 'column_id', required=True, help='ASSIGNMENT ID, of the assignment you want to submit to.') @click.option('-at', '--attempt', 'attempt_id', required=True, help='ATTEMPT ID, of the attempt you want to update.') @attempt_options @@ -120,7 +120,7 @@ def update_attempt(ctx, course_id, column_id, attempt_id, status, comments, subm @click.command(name='grade', help='Grade an assignment.') -@click.option('-c', '--course' ,'course_id', required=True, help='COURSE ID, of the course where the assignment is.') +@click.option('-c', '--course', 'course_id', required=True, help='COURSE ID, of the course where the assignment is.') @click.option('-a', '--assignment', 'column_id', required=True, help='ASSIGNMENT ID, of the assignment you want.') @click.option('-at', '--attempt', 'attempt_id', required=True, help='ATTEMPT ID, of the attempt you want to grade.') @attempt_options diff --git a/bbcli/commands/contents.py b/bbcli/commands/contents.py index b937819ca9a30f7a70075991c2fac17db395a768..8aec8c15bf96a5eef66bfcf85e8f4578f4cbc38b 100644 --- a/bbcli/commands/contents.py +++ b/bbcli/commands/contents.py @@ -3,9 +3,7 @@ from bbcli.utils.error_handler import create_exception_handler, delete_exception import click from bbcli.entities.content_builder_entitites import FileOptions, GradingOptions, StandardOptions, WeblinkOptions from bbcli.services import contents_service -import time import click -import threading import concurrent.futures from bbcli.entities.Node import Node @@ -18,7 +16,7 @@ url_builder = URL_builder() def standard_options(function): function = click.option('-h', '--hide-content', is_flag=True, - help='Hide contents for students')(function) + help='Hide content for students')(function) function = click.option( '-r', '--reviewable', is_flag=True, help='Make content reviewable')(function) function = click.option('--start-date', type=str, @@ -32,11 +30,11 @@ def grading_options(function): function = click.option('-d', '--due-date', type=str, help='Set a sumbission deadline for assignment. Format: DD/MM/YY HH:MM:SS')(function) function = click.option('-a', '--max-attempts', type=int, - help='Set a maximum amount of attempts.')(function) + help='Set maximum amount of attempts')(function) function = click.option('-u', '--unlimited-attempts', - is_flag=True, help='Enable unlimited attempts.')(function) + is_flag=True, help='Enable unlimited attempts')(function) function = click.option('-s', '--score', required=True, - type=int, help='Set assignment score reward.')(function) + type=int, help='Set assignment score reward')(function) return function @@ -51,10 +49,11 @@ def web_link_options(function): 'launch_in_new_window', is_flag=True)(function) return function -@click.command(name='list', help='List the contents. Folders are blue and files are white.') -@click.option('-c', '--course', 'course_id', required=True, type=str, help='COURSE ID, of the course you want to list content from.') -@click.option('-f', '--folder', 'folder_id', required=False, type=str, help='FOLDER ID, of the folder you want to list content from.') -@click.option('-fo', '--folders-only', required=False, is_flag=True, help='Specify this if you want to only list folders.') + +@click.command(name='list', help='List contents\n\nFolders are blue and files are white') +@click.option('-c', '--course', 'course_id', required=True, type=str, help='COURSE ID') +@click.option('-f', '--folder', 'folder_id', required=False, type=str, help='FOLDER ID') +@click.option('-fo', '--folders-only', required=False, is_flag=True, help='List only folders') @click.option('-ct', '--content-type', required=False, type=click.Choice(content_handler.keys(), case_sensitive=False)) @click.pass_context @list_exception_handler @@ -64,9 +63,9 @@ def list_contents(ctx, course_id: str, folder_id: str, content_type, folders_onl else: ct = 'content' if content_type is None else content_type click.echo(f'Listing the {ct}s...') - start = time.time() - response = contents_service.list_contents(ctx.obj['SESSION'], course_id) + response = contents_service.list_contents( + ctx.obj['SESSION'], course_id) data = response.json()['results'] folder_ids = [] node_ids = [] @@ -77,50 +76,54 @@ def list_contents(ctx, course_id: str, folder_id: str, content_type, folders_onl root = Node(node) worklist = [root] folder_ids.append(node['id']) - args = [ctx, course_id, worklist, folder_ids, node_ids, root, folders_only, content_type] + args = [ctx, course_id, worklist, folder_ids, + node_ids, root, folders_only, content_type] t = executor.submit(content_utils.list_contents_thread, *args) threads.append(t) - + for t in threads: root_node = t.result() if root_node is not None: contents_view.list_tree(root_node, folder_ids, node_ids) - else: return + else: + click.ClickException( + 'Cannot list folders only and a specific content type. Try either one.' + ).show() + return - end = time.time() - click.echo(f'Fetch time: {end - start} seconds') - -@click.command(name='get', help='Get a spesific content from a course, using the content id.') -@click.option('-c', '--course', 'course_id', required=True, type=str, help='COURSE ID, of the course you want to get content from.') -@click.option('-co', '--content','node_id', required=True, type=str, help='CONTENT ID, of the content you want to fetch.') +@click.command(name='get', help='Get content') +@click.option('-c', '--course', 'course_id', required=True, type=str, help='COURSE ID') +@click.option('-co', '--content', 'node_id', required=True, type=str, help='CONTENT ID') @click.pass_context @list_exception_handler def get_content(ctx, course_id: str, node_id: str): content_utils.check_content_handler(ctx, course_id, node_id) - -@click.command(name='attachment', help='Adds an attachment to a content. Only supports contents of type document and assignment') -@click.option('-c', '--course', 'course_id', required=True, type=str, help='COURSE ID, of the course where the content is.') -@click.option('-co', '--content', 'content_id', required=True, type=str, help='CONTENT ID, of the content you want to attach a file to.') + +@click.command(name='attachment', help='Add attachment to content\n\nOnly supports contents of type document and assignment') +@click.option('-c', '--course', 'course_id', required=True, type=str, help='COURSE ID of the course where the content is located') +@click.option('-co', '--content', 'content_id', required=True, type=str, help='CONTENT ID of content to attach a file') @click.argument('file_path', required=True, type=click.Path(exists=True)) @click.pass_context @create_exception_handler def upload_attachment(ctx, course_id: str, content_id: str, file_path: str): - contents_service.upload_attachment(ctx.obj['SESSION'], course_id, content_id, file_path) + contents_service.upload_attachment( + ctx.obj['SESSION'], course_id, content_id, file_path) -@click.command(name='document', help='Creates a document content, optionally with file attachments') -@click.option('-c', '--course', 'course_id', required=True, type=str, help='COURSE ID, of the course you want to create content.') -@click.option('-f', '--folder', 'parent_id', required=True, type=str, help='FOLDER ID, of the folder you want to create content in.') +@click.command(name='document', help='Create document content') +@click.option('-c', '--course', 'course_id', required=True, type=str, help='COURSE ID') +@click.option('-f', '--folder', 'parent_id', required=True, type=str, help='FOLDER ID') @click.argument('title', required=True, type=str) @click.argument('attachments', required=False, nargs=-1, type=click.Path()) @standard_options @click.pass_context @create_exception_handler -def create_document(ctx, course_id: str, parent_id: str, title: str, hide_content: bool, reviewable: bool, start_date: str=None, end_date: str=None, attachments: tuple=None): - standard_options = StandardOptions(hide_content=hide_content, reviewable=reviewable) +def create_document(ctx, course_id: str, parent_id: str, title: str, hide_content: bool, reviewable: bool, start_date: str = None, end_date: str = None, attachments: tuple = None): + standard_options = StandardOptions( + hide_content=hide_content, reviewable=reviewable) set_dates(standard_options, start_date, end_date) response = contents_service.create_document( @@ -128,18 +131,18 @@ def create_document(ctx, course_id: str, parent_id: str, title: str, hide_conten click.echo(response) -@click.command(name='file', help='Creates a file content.') -@click.option('-c', '--course', 'course_id', required=True, type=str, help='COURSE ID, of the course where the content exists') -@click.option('-f', '--folder', 'parent_id', required=True, type=str, help='FOLDER ID, of the folder you want to create content in.') +@click.command(name='file', help='Create file content') +@click.option('-c', '--course', 'course_id', required=True, type=str, help='COURSE ID') +@click.option('-f', '--folder', 'parent_id', required=True, type=str, help='FOLDER ID') @click.argument('title', required=True, type=str) @click.argument('file_path', required=True, type=click.Path(exists=True)) @file_options @standard_options @click.pass_context @create_exception_handler -def create_file(ctx, course_id: str, parent_id: str, title: str, file_path: str, - launch_in_new_window:bool, hide_content: bool, reviewable: bool, - start_date: str=None, end_date: str=None): +def create_file(ctx, course_id: str, parent_id: str, title: str, file_path: str, + launch_in_new_window: bool, hide_content: bool, reviewable: bool, + start_date: str = None, end_date: str = None): file_options = FileOptions(launch_in_new_window) standard_options = StandardOptions( hide_content=hide_content, reviewable=reviewable) @@ -149,18 +152,18 @@ def create_file(ctx, course_id: str, parent_id: str, title: str, file_path: str, click.echo(response) -@click.command(name='web-link', help='Create a web link content.') -@click.option('-c', '--course', 'course_id', required=True, type=str, help='COURSE ID, of the course where the content exists') -@click.option('-f', '--folder', 'parent_id', required=True, type=str, help='FOLDER ID, of the folder you want to create content in.') +@click.command(name='web-link', help='Create web link content') +@click.option('-c', '--course', 'course_id', required=True, type=str, help='COURSE ID') +@click.option('-f', '--folder', 'parent_id', required=True, type=str, help='FOLDER ID') @click.argument('title', required=True, type=str) @click.argument('url', required=True, type=str) @standard_options @web_link_options @click.pass_context @create_exception_handler -def create_web_link(ctx, course_id: str, parent_id: str, title: str, url: str, - launch_in_new_window:bool, hide_content: bool, reviewable: bool, - start_date: str=None, end_date: str=None): +def create_web_link(ctx, course_id: str, parent_id: str, title: str, url: str, + launch_in_new_window: bool, hide_content: bool, reviewable: bool, + start_date: str = None, end_date: str = None): web_link_options = WeblinkOptions(launch_in_new_window) standard_options = StandardOptions(hide_content, reviewable) set_dates(standard_options, start_date, end_date) @@ -169,43 +172,45 @@ def create_web_link(ctx, course_id: str, parent_id: str, title: str, url: str, click.echo(response) -@click.command(name='folder', help='Create a folder either in top level or inside another content.') -@click.option('-c', '--course', 'course_id', required=True, type=str, help='COURSE ID, of the course where the content exists') -@click.option('-f', '--folder', 'parent_id', required=False, type=str, help='FOLDER ID, of the folder you want to create folder in.') +@click.command(name='folder', help='Create folder') +@click.option('-c', '--course', 'course_id', required=True, type=str, help='COURSE ID') +@click.option('-f', '--folder', 'parent_id', required=False, type=str, help='FOLDER ID of the parent folder') @click.argument('title', required=True, type=str) @click.option('--is-bb-page', is_flag=True, help='Make folder a blackboard page') @standard_options @click.pass_context @create_exception_handler def create_folder(ctx, course_id: str, parent_id: str, title: str, - hide_content: bool, reviewable: bool, is_bb_page: bool = False, - start_date: str=None, end_date: str=None): + hide_content: bool, reviewable: bool, is_bb_page: bool = False, + start_date: str = None, end_date: str = None): standard_options = StandardOptions(hide_content, reviewable) set_dates(standard_options, start_date, end_date) response = contents_service.create_folder( ctx.obj['SESSION'], course_id, parent_id, title, is_bb_page, standard_options) click.echo(response) - -@click.command(name='course-link', help='Create a course link content which redirects user to the target content.') -@click.option('-c', '--course', 'course_id', required=True, type=str, help='COURSE ID, of the course where the content exists') -@click.option('-f', '--folder', 'parent_id', required=True, type=str, help='FOLDER ID, of the folder you want to create content in.') + + +@click.command(name='course-link', help='Create course link content\n\nRedirects user to the target content') +@click.option('-c', '--course', 'course_id', required=True, type=str, help='COURSE ID') +@click.option('-f', '--folder', 'parent_id', required=True, type=str, help='FOLDER ID') @click.argument('title', required=True, type=str) @click.argument('target_id', required=True, type=str) @standard_options @click.pass_context @create_exception_handler def create_courselink(ctx, course_id: str, parent_id: str, title: str, target_id: str, - hide_content: bool, reviewable: bool, - start_date: str=None, end_date: str=None): + hide_content: bool, reviewable: bool, + start_date: str = None, end_date: str = None): standard_options = StandardOptions(hide_content, reviewable) set_dates(standard_options, start_date, end_date) response = contents_service.create_courselink( ctx.obj['SESSION'], course_id, parent_id, title, target_id, standard_options) click.echo(response) - -@click.command(name='assignment', help='Creates an assignment.') -@click.option('-c', '--course', 'course_id', required=True, type=str, help='COURSE ID, of the course where the content exists') -@click.option('-f', '--folder', 'parent_id', required=True, type=str, help='FOLDER ID, of the folder you want to create content in.') + + +@click.command(name='assignment', help='Create assignment') +@click.option('-c', '--course', 'course_id', required=True, type=str, help='COURSE ID') +@click.option('-f', '--folder', 'parent_id', required=True, type=str, help='FOLDER ID') @click.argument('title', required=True, type=str) @click.argument('attachments', required=False, nargs=-1, type=click.Path()) @standard_options @@ -213,12 +218,12 @@ def create_courselink(ctx, course_id: str, parent_id: str, title: str, target_id @click.pass_context @create_exception_handler def create_assignment_from_contents(ctx, course_id: str, parent_id: str, title: str, - hide_content: bool, reviewable: bool, - start_date: str, end_date: str, - due_date: str, max_attempts: int, unlimited_attempts: bool, score: int, - attachments: tuple): + hide_content: bool, reviewable: bool, + start_date: str, end_date: str, + due_date: str, max_attempts: int, unlimited_attempts: bool, score: int, + attachments: tuple): """ - Creates an assignment. + Create assignment """ standard_options = StandardOptions(hide_content, reviewable) grading_options = GradingOptions( @@ -233,24 +238,28 @@ def create_assignment_from_contents(ctx, course_id: str, parent_id: str, title: # TODO: ADD RESPONSES -@click.command(name='delete', help='Deletes a content.') -@click.option('-c', '--course', 'course_id', required=True, type=str, help='COURSE ID, of the course where the content exists') -@click.option('-co', '--content', 'content_id', required=True, type=str, help='CONTENT ID, of the content you want to delete.') -@click.option('--delete-grades', is_flag=True, help='Deletes grades if a grade column is assosciated with the content.') +@click.command(name='delete', help='Delete content') +@click.option('-c', '--course', 'course_id', required=True, type=str, help='COURSE ID') +@click.option('-co', '--content', 'content_id', required=True, type=str, help='CONTENT ID') +@click.option('--delete-grades', is_flag=True, help='Delete grades if a grade column is associated with the content') @click.pass_context @delete_exception_handler def delete_content(ctx, course_id: str, content_id: str, delete_grades: bool): - response = contents_service.delete_content(ctx.obj['SESSION'], course_id, content_id, delete_grades) + response = contents_service.delete_content( + ctx.obj['SESSION'], course_id, content_id, delete_grades) click.echo(response) # TODO: ADD RESPONSES -@click.command(name='update', help='Updates a given content.\nEditable content types: document, files, assignments, externallinks, courselinks') -@click.option('-c', '--course', 'course_id', required=True, type=str, help='COURSE ID, of the course where the content exists.') -@click.option('-co', '--content', 'content_id', required=True, type=str, help='CONTENT ID, of the content you want to update.') + + +@click.command(name='update', help='Update content\n\nEditable content types: document, files, assignments, externallinks, courselinks') +@click.option('-c', '--course', 'course_id', required=True, type=str, help='COURSE ID.') +@click.option('-co', '--content', 'content_id', required=True, type=str, help='CONTENT ID') @click.pass_context @update_exception_handler def update_content(ctx, course_id: str, content_id: str): - response = contents_service.update_content(ctx.obj['SESSION'], course_id, content_id) + response = contents_service.update_content( + ctx.obj['SESSION'], course_id, content_id) click.echo(response) diff --git a/bbcli/commands/courses.py b/bbcli/commands/courses.py index 1c71768c8e31c816cbb01b2bdbd926a898d3149f..39f063c33b7b58b064249095cf1cc617c6ac86ce 100644 --- a/bbcli/commands/courses.py +++ b/bbcli/commands/courses.py @@ -6,10 +6,10 @@ import os import requests -#, help='List a spesific course with the corresponding id' -@click.command(name='list', help='This command lists your courses, by default only the courses from two last semesters.') -@click.option('-c', '--course', 'course_id', required=False, type=str, help='COURSE ID, search for spesific course') -@click.option('-a', '--all/--no-all', 'show_all', default=False, help='Lists all courses you have ever been signed up for') +# , help='List a spesific course with the corresponding id' +@click.command(name='list', help='List courses') +@click.option('-c', '--course', 'course_id', required=False, type=str, help='[COURSE ID] Get information about a specific course') +@click.option('-a', '--all/--no-all', 'show_all', default=False, help='List all registered courses on the current user') @click.pass_context @list_exception_handler def list_courses(ctx, course_id=None, show_all=False): diff --git a/bbcli/entities/Node.py b/bbcli/entities/Node.py index 1fdeb2c784b845f8870da13317ade2a0799b9a6c..b2b02effcef64a77bbb213f256c475cc238de798 100644 --- a/bbcli/entities/Node.py +++ b/bbcli/entities/Node.py @@ -15,13 +15,13 @@ class Node: def preorder(self): root = self - root_node = Nd(root.data['title'], **{'node_id' : root.data['id']}) + root_node = Nd(root.data['id'] + ' ' + root.data['title']) def dfs(node: Node, root_node: Nd, parent: Nd) -> None: if not node: return elif parent is None: parent = root_node else: - nd = Nd(node.data['title'], parent, **{'node_id' : node.data['id']}) + nd = Nd(node.data['id'] + ' ' + node.data['title'], parent) parent = nd for c in node.children: dfs(c, root_node, parent) diff --git a/bbcli/services/authorization_service.py b/bbcli/services/authorization_service.py index 68f74f51c4e7228dd62be84afb7f789533ea9fac..85e665e6ac2f1859913f15e212de16b14814977c 100644 --- a/bbcli/services/authorization_service.py +++ b/bbcli/services/authorization_service.py @@ -21,6 +21,7 @@ saml_response = None # TODO: Add better error handling here. WIth try catch etc. + def login(): click.echo("Logging in...") # TODO: Let user choose between feide log in or ID-gate diff --git a/bbcli/utils/content_utils.py b/bbcli/utils/content_utils.py index 0407e7335464c907e26972d109fc9cbb9c580787..db9cbb03447c3800fdac7c12d6f1724a22711a2e 100644 --- a/bbcli/utils/content_utils.py +++ b/bbcli/utils/content_utils.py @@ -13,14 +13,14 @@ def is_folder(node): def get_children(ctx, course_id, worklist, folder_ids, node_ids): if len(worklist) == 0: - return + return else: node = worklist.pop(0) node_id = node.data['id'] response = contents_service.get_children( ctx.obj['SESSION'], course_id, node_id) if check_response(response) == False: - pass + return else: children = response.json()['results'] for child in children: @@ -44,7 +44,7 @@ def get_folders(ctx, course_id, worklist, folder_ids, node_ids): response = contents_service.get_children( ctx.obj['SESSION'], course_id, node_id) if check_response(response) == False: - pass + return else: children = response.json()['results'] for child in children: @@ -66,7 +66,7 @@ def get_content_type(ctx, course_id, worklist, folder_ids, node_ids, content_typ response = contents_service.get_children( ctx.obj['SESSION'], course_id, node_id) if check_response(response) == False: - pass + return else: children = response.json()['results'] for child in children: @@ -91,14 +91,13 @@ def list_contents_thread( folder_ids, node_ids, root, - folders: bool, + folders_only: bool, content_type: str): - if folders and content_type is not None: - click.ClickException( - 'Cannot list contents and a specific folder type. Try either one.') - elif folders and content_type is None: + if folders_only and content_type is not None: + return + elif folders_only and content_type is None: get_folders(ctx, course_id, worklist, folder_ids, node_ids) - elif folders == False and content_type is not None: + elif folders_only == False and content_type is not None: get_content_type(ctx, course_id, worklist, folder_ids, node_ids, content_type) else: get_children(ctx, course_id, worklist, folder_ids, node_ids) diff --git a/bbcli/utils/utils.py b/bbcli/utils/utils.py index d43705a285507272ecbd7b225aaef915679960a8..071dabea6f80852769fcd4bf29269459a3759607 100644 --- a/bbcli/utils/utils.py +++ b/bbcli/utils/utils.py @@ -1,7 +1,7 @@ import os from datetime import datetime import mmap -from typing import Dict, List +from typing import List from requests import Session import html2text import click diff --git a/bbcli/views/contents_view.py b/bbcli/views/contents_view.py index 764a12200e1799dbf33f58135e58cd84f1955cca..39f320edbddc7c33796cfb224550e30bf028ad9c 100644 --- a/bbcli/views/contents_view.py +++ b/bbcli/views/contents_view.py @@ -9,24 +9,22 @@ def list_tree(root, folder_ids, node_ids): # color = Fore.RESET if only_folders else Fore.BLUE color = Fore.BLUE for pre, fill, node in RenderTree(root): - node_id = None - if 'node_id' in dir(node): - node_id = getattr(node, 'node_id') - else: - click.echo('Could not retreive the node id.') + node_id = node.name.split()[0] if node_id in folder_ids: - click.echo(f'{pre}{color}{node_id} {node.name} {Style.RESET_ALL}') + click.echo(f'{pre}{color} {node.name} {Style.RESET_ALL}') elif node_id in node_ids: - click.echo(f'{pre}{node_id} {node.name}') + click.echo(f'{pre} {node.name}') else: click.echo('Neither node nor folder.') + + def open_vim(data): str = data['title'] + '\n' str += html_to_text(data['body']) - EDITOR = os.environ.get('EDITOR','vim') #that easy! + EDITOR = os.environ.get('EDITOR','vim') initial_message = bytearray(str, encoding='utf8')