diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000000000000000000000000000000000000..335ea9d070ad1c319906aeff798584ded23c7387 --- /dev/null +++ b/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2018 The Python Packaging Authority + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/README.md b/README.md index cacf928aba83eddd087db5dcc049a54585abce35..9faf7d68ceb3794ebf0c73e58de4d9c09fc2fc40 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,3 @@ -# snipper - - -## Deployment info +# Snip +A lightweight framework for removing code from student solutions. Currently used at DTU. diff --git a/__init__.py b/__init__.py deleted file mode 100644 index e6c4c87033382eeafd151eb0589f418af9563285..0000000000000000000000000000000000000000 --- a/__init__.py +++ /dev/null @@ -1,35 +0,0 @@ -import os - -# DONT't import stuff here since install script requires __version__ - -def cache_write(object, file_name, verbose=True): - import compress_pickle - dn = os.path.dirname(file_name) - if not os.path.exists(dn): - os.mkdir(dn) - if verbose: print("Writing cache...", file_name) - with open(file_name, 'wb', ) as f: - compress_pickle.dump(object, f, compression="lzma") - if verbose: print("Done!") - - -def cache_exists(file_name): - # file_name = cn_(file_name) if cache_prefix else file_name - return os.path.exists(file_name) - - -def cache_read(file_name): - import compress_pickle # Import here because if you import in top the __version__ tag will fail. - # file_name = cn_(file_name) if cache_prefix else file_name - if os.path.exists(file_name): - try: - with open(file_name, 'rb') as f: - return compress_pickle.load(f, compression="lzma") - except Exception as e: - print("Tried to load a bad pickle file at", file_name) - print("If the file appears to be automatically generated, you can try to delete it, otherwise download a new version") - print(e) - # return pickle.load(f) - else: - return None - diff --git a/dist/codesnipper-0.0.1-py3-none-any.whl b/dist/codesnipper-0.0.1-py3-none-any.whl new file mode 100644 index 0000000000000000000000000000000000000000..aaf5ead48e7a089977e5499028f603aea1e06382 Binary files /dev/null and b/dist/codesnipper-0.0.1-py3-none-any.whl differ diff --git a/dist/codesnipper-0.0.1.tar.gz b/dist/codesnipper-0.0.1.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..10f2113f9f53428f684c11322062001fb42571d2 Binary files /dev/null and b/dist/codesnipper-0.0.1.tar.gz differ diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000000000000000000000000000000000000..b5a3c468d9e85e7fa7469c3a90d47b48ab93e54a --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,6 @@ +[build-system] +requires = [ + "setuptools>=42", + "wheel" +] +build-backend = "setuptools.build_meta" \ No newline at end of file diff --git a/setup.py b/setup.py index 5b02a2c7a341496568686e8bc5dfdf87e4dbcb19..72a886d131a19dcb74d4e37bd21dc1928e2aeaa2 100644 --- a/setup.py +++ b/setup.py @@ -1,38 +1,48 @@ -from setuptools import setup +# Use this guide: +# https://packaging.python.org/tutorials/packaging-projects/ +# from unitgrade2.version import __version__ import setuptools -from src.snipper.version import __version__ +# with open("src/unitgrade2/version.py", "r", encoding="utf-8") as fh: +# __version__ = fh.read().split(" = ")[1].strip()[1:-1] +# long_description = fh.read() with open("README.md", "r", encoding="utf-8") as fh: long_description = fh.read() -setup( - name="example-pkg-YOUR-USERNAME-HERE", - version=__version__, +setuptools.setup( + name="codesnipper", + version="0.0.1", author="Tue Herlau", author_email="tuhe@dtu.dk", - description="A small example package", + description="A lightweight framework for censoring student solutions files and extracting code + output", long_description=long_description, long_description_content_type="text/markdown", - url="https://compute.dtu.dk/tuhe/snipper", - # project_urls={ - #"Bug Tracker": "https://github.com/pypa/sampleproject/issues", - # }, + license="MIT", + url='https://lab.compute.dtu.dk/tuhe/snipper', + project_urls={ + "Bug Tracker": "https://lab.compute.dtu.dk/tuhe/snipper/issues", + }, classifiers=[ "Programming Language :: Python :: 3", - # "License :: OSI Approved :: MIT License", + "License :: OSI Approved :: MIT License", "Operating System :: OS Independent", ], - package_dir={"src"}, + package_dir={"": "src"}, packages=setuptools.find_packages(where="src"), - python_requires=">=3.6", - install_requires=['numpy', 'jinja2', 'tabulate', 'sklearn', 'compress_pickle', "pyfiglet"], - # name='homework-snipper-tuhe', - # version=__version__, - # packages=['snipper'], - # url='https://lab.compute.dtu.dk/tuhe/unitgrade', - # license='Apache', - # author='Tue Herlau', - # author_email='tuhe@dtu.dk', - # description='A lightweight student evaluation framework build on unittest', - # include_package_data=True, + python_requires=">=3.8", + install_requires=['jinja2',], ) + +# setup( +# name='unitgrade', +# version=__version__, +# packages=['unitgrade2'], +# url=, +# license='MIT', +# author='Tue Herlau', +# author_email='tuhe@dtu.dk', +# description=""" +# A student homework/exam evaluation framework build on pythons unittest framework. This package contains all files required to run unitgrade tests as a student. To develop tests, please use unitgrade_private. +# """, +# include_package_data=False, +# ) diff --git a/src/codesnipper.egg-info/PKG-INFO b/src/codesnipper.egg-info/PKG-INFO new file mode 100644 index 0000000000000000000000000000000000000000..487bc49d1a1da8cad30d409ce4d898b017babc34 --- /dev/null +++ b/src/codesnipper.egg-info/PKG-INFO @@ -0,0 +1,22 @@ +Metadata-Version: 2.1 +Name: codesnipper +Version: 0.0.1 +Summary: A lightweight framework for censoring student solutions files and extracting code + output +Home-page: https://lab.compute.dtu.dk/tuhe/snipper +Author: Tue Herlau +Author-email: tuhe@dtu.dk +License: UNKNOWN +Project-URL: Bug Tracker, https://lab.compute.dtu.dk/tuhe/snipper/issues +Platform: UNKNOWN +Classifier: Programming Language :: Python :: 3 +Classifier: License :: OSI Approved :: MIT License +Classifier: Operating System :: OS Independent +Requires-Python: >=3.8 +Description-Content-Type: text/markdown +License-File: LICENSE + +# Snip +A lightweight framework for removing code from student solutions. Currently used at DTU. + + + diff --git a/src/codesnipper.egg-info/SOURCES.txt b/src/codesnipper.egg-info/SOURCES.txt new file mode 100644 index 0000000000000000000000000000000000000000..8b9ec963f866926c6443dfdfdce0f0fd577af5ee --- /dev/null +++ b/src/codesnipper.egg-info/SOURCES.txt @@ -0,0 +1,13 @@ +LICENSE +MANIFEST.in +README.md +pyproject.toml +setup.py +src/codesnipper.egg-info/PKG-INFO +src/codesnipper.egg-info/SOURCES.txt +src/codesnipper.egg-info/dependency_links.txt +src/codesnipper.egg-info/requires.txt +src/codesnipper.egg-info/top_level.txt +src/snipper/__init__.py +src/snipper/snip_dir.py +src/snipper/snipper.py \ No newline at end of file diff --git a/src/codesnipper.egg-info/dependency_links.txt b/src/codesnipper.egg-info/dependency_links.txt new file mode 100644 index 0000000000000000000000000000000000000000..8b137891791fe96927ad78e64b0aad7bded08bdc --- /dev/null +++ b/src/codesnipper.egg-info/dependency_links.txt @@ -0,0 +1 @@ + diff --git a/src/codesnipper.egg-info/requires.txt b/src/codesnipper.egg-info/requires.txt new file mode 100644 index 0000000000000000000000000000000000000000..7f7afbf3bf54b346092be6a72070fcbd305ead1e --- /dev/null +++ b/src/codesnipper.egg-info/requires.txt @@ -0,0 +1 @@ +jinja2 diff --git a/src/codesnipper.egg-info/top_level.txt b/src/codesnipper.egg-info/top_level.txt new file mode 100644 index 0000000000000000000000000000000000000000..76fe62131e1501f411b1a794339b80b4e1e5a541 --- /dev/null +++ b/src/codesnipper.egg-info/top_level.txt @@ -0,0 +1 @@ +snipper diff --git a/src/snip.egg-info/PKG-INFO b/src/snip.egg-info/PKG-INFO new file mode 100644 index 0000000000000000000000000000000000000000..8ea5f2f881c7580a739c683815a23a5a6677c7f6 --- /dev/null +++ b/src/snip.egg-info/PKG-INFO @@ -0,0 +1,22 @@ +Metadata-Version: 2.1 +Name: snip +Version: 0.0.1 +Summary: A lightweight framework for censoring student solutions files and extracting code +Home-page: https://lab.compute.dtu.dk/tuhe/snipper +Author: Tue Herlau +Author-email: tuhe@dtu.dk +License: UNKNOWN +Project-URL: Bug Tracker, https://lab.compute.dtu.dk/tuhe/snipper/issues +Platform: UNKNOWN +Classifier: Programming Language :: Python :: 3 +Classifier: License :: OSI Approved :: MIT License +Classifier: Operating System :: OS Independent +Requires-Python: >=3.8 +Description-Content-Type: text/markdown +License-File: LICENSE + +# Snip +A lightweight framework for removing code from student solutions. Currently used at DTU. + + + diff --git a/src/snip.egg-info/SOURCES.txt b/src/snip.egg-info/SOURCES.txt new file mode 100644 index 0000000000000000000000000000000000000000..bd0aac6996b39d8a2260fc2eb3db3c16069f42f4 --- /dev/null +++ b/src/snip.egg-info/SOURCES.txt @@ -0,0 +1,13 @@ +LICENSE +MANIFEST.in +README.md +pyproject.toml +setup.py +src/snip.egg-info/PKG-INFO +src/snip.egg-info/SOURCES.txt +src/snip.egg-info/dependency_links.txt +src/snip.egg-info/requires.txt +src/snip.egg-info/top_level.txt +src/snipper/__init__.py +src/snipper/snip_dir.py +src/snipper/snipper.py \ No newline at end of file diff --git a/src/snip.egg-info/dependency_links.txt b/src/snip.egg-info/dependency_links.txt new file mode 100644 index 0000000000000000000000000000000000000000..8b137891791fe96927ad78e64b0aad7bded08bdc --- /dev/null +++ b/src/snip.egg-info/dependency_links.txt @@ -0,0 +1 @@ + diff --git a/src/snip.egg-info/requires.txt b/src/snip.egg-info/requires.txt new file mode 100644 index 0000000000000000000000000000000000000000..7f7afbf3bf54b346092be6a72070fcbd305ead1e --- /dev/null +++ b/src/snip.egg-info/requires.txt @@ -0,0 +1 @@ +jinja2 diff --git a/src/snip.egg-info/top_level.txt b/src/snip.egg-info/top_level.txt new file mode 100644 index 0000000000000000000000000000000000000000..76fe62131e1501f411b1a794339b80b4e1e5a541 --- /dev/null +++ b/src/snip.egg-info/top_level.txt @@ -0,0 +1 @@ +snipper diff --git a/src/snipper/__init__.py b/src/snipper/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..b4376007ee3f8f65caa49519afc7a4d1c3c6bf88 --- /dev/null +++ b/src/snipper/__init__.py @@ -0,0 +1 @@ +__version__ == "0.0.1" diff --git a/src/snipper/__pycache__/snip_dir.cpython-38.pyc b/src/snipper/__pycache__/snip_dir.cpython-38.pyc index 90c94e065160551d01fbfaf907b3f93611e62869..50eb77d4a6c15593ccc6bfb963a021aa51a4b489 100644 Binary files a/src/snipper/__pycache__/snip_dir.cpython-38.pyc and b/src/snipper/__pycache__/snip_dir.cpython-38.pyc differ diff --git a/src/snipper/__pycache__/snipper.cpython-38.pyc b/src/snipper/__pycache__/snipper.cpython-38.pyc index 76ee5eb7cb4c254035e4eadec59eb0389b6faf46..71b07e1eb0fc48f94614ddd3c0c39e38faeb6047 100644 Binary files a/src/snipper/__pycache__/snipper.cpython-38.pyc and b/src/snipper/__pycache__/snipper.cpython-38.pyc differ diff --git a/src/snipper/snip_dir.py b/src/snipper/snip_dir.py index 4d2ff272499fe11d18c3e2dbeed1c39be68e93f2..ca985685e80e703d1ea4eb0c2aecff10423dd916 100644 --- a/src/snipper/snip_dir.py +++ b/src/snipper/snip_dir.py @@ -12,7 +12,9 @@ def snip_dir(source_dir, dest_dir, exclude=None, clean_destination_dir=True): exclude = [] if not os.path.exists(dest_dir): os.makedirs(dest_dir) - if os.path.samefile(source_dir, dest_dir): + source_dir = os.path.abspath(source_dir) + dest_dir = os.path.abspath(dest_dir) + if os.path.samefile( source_dir, dest_dir): raise Exception("Source and destination is the same") if clean_destination_dir: shutil.rmtree(dest_dir) @@ -25,7 +27,7 @@ def snip_dir(source_dir, dest_dir, exclude=None, clean_destination_dir=True): # def fix_hw(info, hw, out, run_files=False, cut_files=False, students_irlc_tools=None, **kwargs): # CE = info['CE'] # paths = get_paths() - print(f"Fixing {hw['base']} -> {out}") + print(f"[snipper] Synchronizing directories: {hw['base']} -> {out}") if os.path.exists(out): shutil.rmtree(out) diff --git a/src/snipper/snipper.py b/src/snipper/snipper.py index 1c0a3d3a3db5600c0f28f7ebafe669e1a2110ffc..386a36038fe1566cc60e95eb90542137306f2d76 100644 --- a/src/snipper/snipper.py +++ b/src/snipper/snipper.py @@ -286,17 +286,22 @@ def fix_f(lines, debug): comments = [id + c for c in comments] if len(comments) > 0: lines2 += comments[0].split("\n") - lines2 += [id+"#!b"] - lines2 += (id+funrem.strip()).split("\n") + # lines2 += [id+"#!b"] + f = [id + l.strip() for l in funrem.splitlines()] + f[0] = f[0] + "#!b" + + # lines2 += (id+funrem.strip()).split("\n") errm = l_head if len(l_head) > 0 else "Implement function body" - lines2 += [f'{id}#!b {errm}'] + f[-1] = f[-1] + f' #!b {errm}' + lines2 += f + # lines2 += [f'{id}#!b {errm}'] else: lines2.append(l) i += 1 return lines2 -def fix_b2(lines): +def fix_b2(lines, keep=False): stats = {'n': 0} def block_fun(lines, start_extra, end_extra, art, stats=None, **kwargs): id = indent(lines[0]) @@ -307,8 +312,12 @@ def fix_b2(lines): if len(ee) >= 2 and ee[0] == '"': ee = ee[1:-1] start_extra = start_extra.strip() - l2 = ([id+start_extra] if len(start_extra) > 0 else []) + [id + f"# TODO: {cc} lines missing.", - id+f'raise NotImplementedError("{ee}")'] + if keep: + l2 = ['GARBAGE'] * cc + else: + l2 = ([id+start_extra] if len(start_extra) > 0 else []) + [id + f"# TODO: {cc} lines missing.", id+f'raise NotImplementedError("{ee}")'] + + # if "\n".join(l2).find("l=l")>0: # a = 2342342 stats['n'] += cc @@ -386,6 +395,17 @@ def full_strip(lines, tags=None): lines = strip_tag(lines, t) return lines + +def censor_code(lines, keep=True): + # lines = code.split("\n") + dbug = True + lines = fix_f(lines, dbug) + lines, nB, cut = fix_b2(lines, keep=True) + return lines + + # print("safs") + + def censor_file(file, info, paths, run_files=True, run_out_dirs=None, cut_files=True, solution_list=None, censor_files=True, include_path_base=None, diff --git a/src/snipper/version.py b/src/snipper/version.py deleted file mode 100644 index f102a9cadfa89ce554b3b26d2b90bfba2e05273c..0000000000000000000000000000000000000000 --- a/src/snipper/version.py +++ /dev/null @@ -1 +0,0 @@ -__version__ = "0.0.1"