def cmd_open(course_code: str, project_id: Optional[str], file: Optional[str]): """Open projects or files. Paths can be used to specify directory or files within projects to open. """ if project_id is None: # Open course path = str(path_helper.get_path(course_code)) os.system(f'open "{path}"') else: check_project_exists(course_code, project_id) if file is None: # Open project with open_method in settings # If not set or error reading settings, default to open by path settings = project_helper.read_project_settings(course_code, project_id) path = path_helper.get_path(course_code, project_id) if settings is not None and settings.open_method is not None: # Use project's open_method if possible os.system(f'cd "{path}"; {settings.open_method}') else: os.system(f'open "{path}"') else: path = str(path_helper.get_path(course_code, project_id, file)) os.system(f'open "{path}"')
def add_course(course_code: str): """Add a new course with code <course_code>. Preconditions: - the course code is valid - the course does not already exist or in archive """ path_helper.get_path(course_code).mkdir(parents=True)
def unarchive_course(course_code: str): """Move the course with code <course_code> from archived to courses. Preconditions: - the course code is valid - the course exists in archive """ src = path_helper.get_path(ARCHIVED_DIRECTORY, course_code) dest = path_helper.get_path(course_code) shutil.move(str(src), str(dest))
def _get_file_path(scope: TodoScope) -> str: """Get the path string to the todo json file given <scope>.""" if scope is None: return str(path_helper.get_path(TODO_FILENAME)) elif isinstance(scope, str): return str(path_helper.get_path(scope, TODO_FILENAME)) else: # TODO: check projects in subdirectories (possible in future) course_code, project_id = scope return str(path_helper.get_path(course_code, project_id, TODO_FILENAME))
def remove_course(course_code: str): """Remove the course with code <course_code> Preconditions: - the course code is valid - the course exists """ shutil.rmtree(path_helper.get_path(course_code))
def delete_project(course_code: str, project_id: str): """Delete the project with given course code and project id. Preconditions: - the course with <course_code> exists - the project with <project_id> exists in the course """ shutil.rmtree(path_helper.get_path(course_code, project_id))
def create_project(course_code: str, settings: ProjectSettings): """Create a new project with given course code and settings. Preconditions: - the course with <course_code> exists - the project id is valid and unique from other projects of the same course """ project_dir = path_helper.get_path(course_code, settings.project_id) project_dir.mkdir(parents=True) write_project_settings(course_code, settings)
def write_project_settings(course_code: str, settings: ProjectSettings): """Write project settings to file. Preconditions: - the course with <course_code> exists - the project directory exists """ settings_path = path_helper.get_path(course_code, settings.project_id, PROJECT_SETTINGS_FILE) with open(str(settings_path), 'w') as f: f.write(settings.to_json())
def get_project_ids(course_code: str) -> List[str]: """Return the list of ids of the course's projects. Precondition: the course with <course_code> exists. """ project_ids = [] for path in path_helper.get_path(course_code).iterdir(): if path.is_dir(): project_ids.append(path.name) return project_ids
def read_project_settings(course_code: str, project_id: str) -> Optional[ProjectSettings]: """Read project settings of project with id. Return None if the settings file does not exist, or if the content cannot be parsed. Preconditions: - the course with <course_code> exists - the project directory exists """ settings_path = path_helper.get_path(course_code, project_id, PROJECT_SETTINGS_FILE) try: with open(str(settings_path), 'r') as f: content = f.read() return ProjectSettings.from_json(content) except FileNotFoundError: return None
def get_template_path(template: str, course_code: Optional[str] = None) -> path_helper.Path: """Get the path to template.""" if course_code is not None: return path_helper.get_path(course_code, TEMPLATES_DIRECTORY, template) return path_helper.get_path(TEMPLATES_DIRECTORY, template)
def get_archived_course_codes() -> List[str]: """Get the list of course codes of archived courses, sorted alphabetically.""" return _get_course_codes(path_helper.get_path(ARCHIVED_DIRECTORY))
def course_archived(course_code: str) -> bool: """Return True iff the course with <course_code> exists in archive. Precondition: the course code is valid. """ return path_helper.get_path(ARCHIVED_DIRECTORY, course_code).exists()
def course_exists(course_code: str) -> bool: """Return True iff the course with <course_code> exists. Precondition: the course code is valid. """ return path_helper.get_path(course_code).exists()
def project_exists(course_code: str, project_id: str) -> bool: """Check whether the project with <project_id> exist in course with <course_code>.""" return path_helper.get_path(course_code, project_id).is_dir()