From 3905d6334d9df05521da9469dea9b2fda81c7d01 Mon Sep 17 00:00:00 2001 From: Kushal Das Date: Fri, 10 Aug 2018 14:48:46 +0530 Subject: [PATCH 1/4] Updates format using black --- docs/conf.py | 57 ++++++++++++++++++++++++---------------------------- setup.py | 6 +++--- 2 files changed, 29 insertions(+), 34 deletions(-) diff --git a/docs/conf.py b/docs/conf.py index 3b9e411a9..cf74f7412 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -19,14 +19,14 @@ # -- Project information ----------------------------------------------------- -project = 'sdconfigapi' -copyright = '2018, Kushal Das' -author = 'Kushal Das ' +project = "sdconfigapi" +copyright = "2018, Kushal Das" +author = "Kushal Das " # The short X.Y version -version = '0.1.0' +version = "0.1.0" # The full version, including alpha/beta/rc tags -release = '0.1.0' +release = "0.1.0" # -- General configuration --------------------------------------------------- @@ -38,23 +38,19 @@ # Add any Sphinx extension module names here, as strings. They can be # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom # ones. -extensions = [ - 'sphinx.ext.autodoc', - 'sphinx.ext.intersphinx', - 'sphinx.ext.viewcode', -] +extensions = ["sphinx.ext.autodoc", "sphinx.ext.intersphinx", "sphinx.ext.viewcode"] # Add any paths that contain templates here, relative to this directory. -templates_path = ['_templates'] +templates_path = ["_templates"] # The suffix(es) of source filenames. # You can specify multiple suffix as a list of string: # # source_suffix = ['.rst', '.md'] -source_suffix = '.rst' +source_suffix = ".rst" # The master toctree document. -master_doc = 'index' +master_doc = "index" # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. @@ -66,10 +62,10 @@ # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. # This pattern also affects html_static_path and html_extra_path . -exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store'] +exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"] # The name of the Pygments (syntax highlighting) style to use. -pygments_style = 'sphinx' +pygments_style = "sphinx" # -- Options for HTML output ------------------------------------------------- @@ -77,7 +73,7 @@ # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. # -html_theme = 'alabaster' +html_theme = "alabaster" # Theme options are theme-specific and customize the look and feel of a theme # further. For a list of options available for each theme, see the @@ -88,7 +84,7 @@ # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". -html_static_path = ['_static'] +html_static_path = ["_static"] # Custom sidebar templates, must be a dictionary that maps document names # to template names. @@ -104,7 +100,7 @@ # -- Options for HTMLHelp output --------------------------------------------- # Output file base name for HTML help builder. -htmlhelp_basename = 'sdconfigapidoc' +htmlhelp_basename = "sdconfigapidoc" # -- Options for LaTeX output ------------------------------------------------ @@ -113,15 +109,12 @@ # The paper size ('letterpaper' or 'a4paper'). # # 'papersize': 'letterpaper', - # The font size ('10pt', '11pt' or '12pt'). # # 'pointsize': '10pt', - # Additional stuff for the LaTeX preamble. # # 'preamble': '', - # Latex figure (float) alignment # # 'figure_align': 'htbp', @@ -131,8 +124,7 @@ # (source start file, target name, title, # author, documentclass [howto, manual, or own class]). latex_documents = [ - (master_doc, 'sdconfigapi.tex', 'sdconfigapi Documentation', - 'Kushal Das', 'manual'), + (master_doc, "sdconfigapi.tex", "sdconfigapi Documentation", "Kushal Das", "manual") ] @@ -140,10 +132,7 @@ # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). -man_pages = [ - (master_doc, 'sdconfigapi', 'sdconfigapi Documentation', - [author], 1) -] +man_pages = [(master_doc, "sdconfigapi", "sdconfigapi Documentation", [author], 1)] # -- Options for Texinfo output ---------------------------------------------- @@ -152,9 +141,15 @@ # (source start file, target name, title, author, # dir menu entry, description, category) texinfo_documents = [ - (master_doc, 'sdconfigapi', 'sdconfigapi Documentation', - author, 'sdconfigapi', 'One line description of project.', - 'Miscellaneous'), + ( + master_doc, + "sdconfigapi", + "sdconfigapi Documentation", + author, + "sdconfigapi", + "One line description of project.", + "Miscellaneous", + ) ] @@ -163,4 +158,4 @@ # -- Options for intersphinx extension --------------------------------------- # Example configuration for intersphinx: refer to the Python standard library. -intersphinx_mapping = {'https://docs.python.org/': None} +intersphinx_mapping = {"https://docs.python.org/": None} diff --git a/setup.py b/setup.py index 565403e28..f4246809d 100644 --- a/setup.py +++ b/setup.py @@ -12,15 +12,15 @@ long_description=long_description, long_description_content_type="text/markdown", install_requires=["requests", "mypy-extensions"], - python_requires='>=3.5', + python_requires=">=3.5", url="https://github.com/freedomofpress/sdclientapi", - packages=setuptools.find_packages(exclude=['docs', 'tests']), + packages=setuptools.find_packages(exclude=["docs", "tests"]), classifiers=( "Development Status :: 3 - Alpha", "Programming Language :: Python :: 3", "Topic :: Software Development :: Libraries :: Python Modules", "License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)", - 'Intended Audience :: Developers', + "Intended Audience :: Developers", "Operating System :: OS Independent", ), ) From 8a422fbfe5ab85f5de6f44f2ad77cb6031277bbf Mon Sep 17 00:00:00 2001 From: Kushal Das Date: Fri, 10 Aug 2018 14:52:01 +0530 Subject: [PATCH 2/4] Adds get and delete source using string Adds two helper function for getting and deleting source using uuid string value. --- sdclientapi/__init__.py | 28 +++++++++++++++++++++++++++- tests/test_api.py | 18 ++++++++++++++++++ 2 files changed, 45 insertions(+), 1 deletion(-) diff --git a/sdclientapi/__init__.py b/sdclientapi/__init__.py index dc8075f7b..323afc4d1 100644 --- a/sdclientapi/__init__.py +++ b/sdclientapi/__init__.py @@ -56,6 +56,7 @@ class Submission: """ This class represents a submission object in the server. """ + def __init__(self, **kwargs) -> None: self.download_url = "" # type: str self.filename = "" # type: str @@ -88,7 +89,8 @@ class Source: """ This class represents a source object in the server. """ - def __init__(self, **kwargs): + + def __init__(self, **kwargs): self.add_star_url = "" # type: str self.interaction_count = 0 # type: int self.is_flagged = False # type: bool @@ -140,6 +142,7 @@ class API: :param totp: Current TOTP value :returns: An object of API class. """ + def __init__(self, address, username, passphrase, totp) -> None: """ Primary API class, this is the only thing which will make network call. @@ -233,6 +236,17 @@ def get_source(self, source: Source) -> Source: return Source(**data) + def get_source_from_string(self, uuid: str) -> Source: + """ + This will fetch a source from server and return it. + + :param uuid: Source UUID as string. + :returns: Source object fetched from server for the given UUID value. + """ + + s = Source(uuid=uuid) + return self.get_source(s) + def delete_source(self, source: Source) -> bool: """ This method will delete the source and collection. If the uuid @@ -262,6 +276,18 @@ def delete_source(self, source: Source) -> bool: # We should never reach here return False + def delete_source_from_string(self, uuid: str) -> bool: + """ + This method will delete the source and collection. If the uuid + is not found in the server, it will raise WrongUUIDError. + + :param uuid: Source UUID as string. + :returns: True if the operation is successful. + """ + + s = Source(uuid=uuid) + return self.delete_source(s) + def add_star(self, source: Source) -> bool: """ Adds a star to a given source. diff --git a/tests/test_api.py b/tests/test_api.py index 95df051fd..686fb39c6 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -73,6 +73,15 @@ def test_get_single_source(self): self.assertEqual(s.journalist_designation, s2.journalist_designation) self.assertEqual(s.uuid, s2.uuid) + @vcr.use_cassette("data/test-get-single-source.yml") + def test_get_single_source_from_string(self): + s = self.api.get_sources()[0] + # Now we will try to get the same source again using uuid + s2 = self.api.get_source_from_string(s.uuid) + + self.assertEqual(s.journalist_designation, s2.journalist_designation) + self.assertEqual(s.uuid, s2.uuid) + @vcr.use_cassette("data/test-failed-single-source.yml") def test_failed_single_source(self): with self.assertRaises(WrongUUIDError): @@ -114,6 +123,15 @@ def test_delete_source(self): sources = self.api.get_sources() self.assertEqual(len(sources), 1) + @vcr.use_cassette("data/test-delete-source.yml") + def test_delete_source_from_string(self): + s = self.api.get_sources()[0] + self.assertTrue(self.api.delete_source_from_string(s.uuid)) + + # Now there should be one source left + sources = self.api.get_sources() + self.assertEqual(len(sources), 1) + @vcr.use_cassette("data/test-delete-submission.yml") def test_delete_submission(self): subs = self.api.get_all_submissions() From 0b12e6f4a749e749717a3c8feb21d43e07e61b01 Mon Sep 17 00:00:00 2001 From: Kushal Das Date: Fri, 10 Aug 2018 17:20:19 +0530 Subject: [PATCH 3/4] Adds get_submission_from_string method It also adds the corresponding test cases. Note: We need both the source and submission uuid to fetch from server. --- data/test-get-submission.yml | 131 +++++++++++++++++++++++++++++++++++ sdclientapi/__init__.py | 17 ++++- tests/test_api.py | 16 +++++ 3 files changed, 163 insertions(+), 1 deletion(-) create mode 100644 data/test-get-submission.yml diff --git a/data/test-get-submission.yml b/data/test-get-submission.yml new file mode 100644 index 000000000..d84d905a1 --- /dev/null +++ b/data/test-get-submission.yml @@ -0,0 +1,131 @@ +interactions: +- request: + body: null + headers: + Accept: [application/json] + Accept-Encoding: ['gzip, deflate'] + Authorization: [token eyJhbGciOiJIUzI1NiIsImV4cCI6MTUzMzkyMzU4NiwiaWF0IjoxNTMzODk0Nzg2fQ.eyJpZCI6MX0.LGxN6cLw-icCD-nuir4jzB4l6Fw44Sv3VERh6ykPzFw] + Connection: [keep-alive] + Content-Type: [application/json] + User-Agent: [python-requests/2.19.1] + method: GET + uri: http://localhost:8081/api/v1/sources + response: + body: {string: "{\n \"sources\": [\n {\n \"add_star_url\": \"/api/v1/sources/4baa4751-7c46-4d0a-a4a4-884a6f44609c/add_star\"\ + , \n \"interaction_count\": 4, \n \"is_flagged\": false, \n \ + \ \"is_starred\": false, \n \"journalist_designation\": \"hard-shelled\ + \ cruet\", \n \"key\": {\n \"public\": \"-----BEGIN PGP PUBLIC\ + \ KEY BLOCK-----\\n\\nmQINBFttYFoBEAC1w4z46Bhg0QkgUwEVq1bvDNaayuCrLQigZbrS4T18HNSSwd1J\\\ + nkvHek0Kxv1ivqzRb3st1qlbnpDZYld9mNnCU86Lap6VOmuwR9dZaBN4Y6ckK/g16\\nTuG+o5oQoG37ZyoObX+aT17aASdR8Y092czFiesI0ypv51/MQeUeC+WCrFV1ZcwC\\\ + nZ+ywAh359VpjtfhF5zqnmtqlrvRQCJeC/1p5YuZZZ4VDLlk9/4VpnD6N9rh32CKk\\noQTG1+5sF3PP5H0yvHdOZT8T0rBx7l9e7hu7q/DJeWX+l9AA/VRqXCZly1ooWabD\\\ + nW1M4hO8C7xKlbe9kY4ZROAE43JoRYm58rP2h8NtXGJxBVlcC1eOD8c6s9Gyd0NUn\\nS3olyQu9aBI6TufenUVzdUbwYNYq7ubQTkaWkHOynYqHXELHP0Gsu8tz46bjAFTE\\\ + nSe9FbZy3H6dPQrSl1jn2sqRXAgwtboPIwe2a3380nR0KC2xBtpu/4JNfp6cfMsHo\\n0gY3fQ6j2nl0VzYlxoqgI0VYOfGVWRIhJu9mpvAtFP6240ILZZVqhkKO1wBPKMHQ\\\ + n/PmTL9XGYIlRgFwEwqpAYI9o8TbtzLqFtVUfBye9GnFnOyT4/yWHHQQ72fvopIXl\\nLhOMNF4+Bpyr1RECYxdb/XrdsiAspYJojUDMq7HikGooRMKNrSoxBl8FyQARAQAB\\\ + ntHxBdXRvZ2VuZXJhdGVkIEtleSA8WjJJR0lQSlhVRTdUM1NSUlNOUEgyR1RQU1E3\\nUDU2RTNGS0FNM01XTVdGUkNYM1REQVZZT0xOVFlBS1hWN1lMSUdSVTZCUTNCQUdY\\\ + nQ05LVzU1UTQ2NUZZQ0w0TFk3R1FXV1ZTQlFJWT0+iQI/BBMBCgApBQJbbWBaAhsv\\nBQkB4VFmBwsJCAcDAgEGFQgCCQoLBBYCAwECHgECF4AACgkQ/vkdUGfshhTcjg//\\\ + ncKii6QJ8mGhCpyALWbTt9spn2aKgvdaUH1b6+jqYslbSwzq2ftoazry7oBQQJT1Z\\ngWRGYFeJ9tXDOYktS2HLK8KLW4WEB0HfzK2pCBHJvIVH+JCRXsRmNvWtcsYYZJ+y\\\ + n4Za8O9q8BPwKXjkssyIts4wDVh2AdlipcUhYRyn4OThGuKiBmRPc8UqhNjMrJMJx\\ncQ6LrraUi/1PVMd2KLC35M5MMubX9QEOEB/dljf+ocwqni/kkGHeMJCKJ7zjfG3n\\\ + ntBjqrsoOOYSKzu6m7ZxzBNSEivVqrKac9GXHmDlk0OhNOOjvompuurLbpnc2hZRQ\\n6yIrB9pIbcm4r4//vZmNyk4xGsQpl7StnepDYA/DT4tSKcq+rhLZPbu7rRudmk+Y\\\ + nWvB3aiA2vk/6LpQy/L71qqlKTVNXbBfFdu8ZvrwF0fSEI/6wN/QFdyr3G9ByuRBn\\nRo65jslrwem3+U77TrLkYCG5x/ONPyAdGshxizczUj/8Rrhh3Dtw0zyAiUgpwjVC\\\ + nN8Y5vZLP3mOphReCWdhgwT1d7xPBOZesuhfrhABTwRIWUjuHDRYtyV0g45IGrbLt\\n49pyXzHah4oOjDMeyItwVh9WGssH4CSyiqHCDMXRoi7FECKbNW+iAdiKLoFviK1E\\\ + nW02GmeDTmDWMBu1igCDfG2I/cTGaqqmDOnsBHwxOJQY=\\n=TTuP\\n-----END PGP PUBLIC\ + \ KEY BLOCK-----\\n\", \n \"type\": \"PGP\"\n }, \n \"last_updated\"\ + : \"2018-08-10T09:52:28.368262Z\", \n \"number_of_documents\": 0, \n\ + \ \"number_of_messages\": 2, \n \"remove_star_url\": \"/api/v1/sources/4baa4751-7c46-4d0a-a4a4-884a6f44609c/remove_star\"\ + , \n \"replies_url\": \"/api/v1/sources/4baa4751-7c46-4d0a-a4a4-884a6f44609c/replies\"\ + , \n \"reply_url\": \"/api/v1/sources/4baa4751-7c46-4d0a-a4a4-884a6f44609c/replies\"\ + , \n \"submissions_url\": \"/api/v1/sources/4baa4751-7c46-4d0a-a4a4-884a6f44609c/submissions\"\ + , \n \"url\": \"/api/v1/sources/4baa4751-7c46-4d0a-a4a4-884a6f44609c\"\ + , \n \"uuid\": \"4baa4751-7c46-4d0a-a4a4-884a6f44609c\"\n }, \n \ + \ {\n \"add_star_url\": \"/api/v1/sources/a8c91c7b-a36d-43f8-930e-e955a77f3c44/add_star\"\ + , \n \"interaction_count\": 4, \n \"is_flagged\": false, \n \ + \ \"is_starred\": false, \n \"journalist_designation\": \"fossilized\ + \ simpleton\", \n \"key\": {\n \"public\": \"-----BEGIN PGP PUBLIC\ + \ KEY BLOCK-----\\n\\nmQINBFttYGIBEAC0SAmZf+jXvCTYM79iGvD8jFgSyi4VBijvv0n99kI05QdoOKgO\\\ + nQTS52jQs8SUwVhAcp6P7ibtywtfA7kfaHU7SWCC1ITIOkGEgOH9gEeTjxt/EF/Jf\\nP6Wlu5+Bi3ZpjMdk/GhmcMOjDr7HxycCgG0UcmVq5RUCV0vQe6Bsz1cv6fakOtUZ\\\ + n7w1hoRODad9CyP4M0a48HRYqjpoVUbD/BbvamA7mOJuwV+O0SrD1w4Yp+8wU2IwZ\\n1Fd9j4S/6bzR1mFv4VaCg/Cm1yTjVsrWNfWduTeXFvJvpnyYu7u5wkIDnhxUqv4v\\\ + nhf2Uw3Z9h6IABq8vHqyol9R/Wo/o9TTcn4FyVQsf3XQh8OeylvDdkI9dKG5WHc6M\\nOf/wjg/LX83cxdDqHzqWuaMQd8B0aDuhDUSOwJuDo/eTsZhnS+iOnIsDE+Dp5cmg\\\ + nHAmfrRKX5rOFLH32eInsZ2W1x/P1XtoB51BcTWgfJpaj+SeRd/B9zjsZf84lpO/q\\nI0l/fXHUkWU8jmZ/KxBJOJ7obivszKhbDjdw6HF9nt/ijoqm5n+OMMxgXP1ENv0Q\\\ + ntZxfFGwRrEqTQ2hQ/x4G/3CK2dPlr1LJzylhacI/E7ZWkE+aWpesR5j6+hM/MFGc\\nlFoZZx6ZIkt3U7vsulicdA9l2YiJX9ZYG9l0EWw0QO4n4N5dOkl+8VZlwQARAQAB\\\ + ntHxBdXRvZ2VuZXJhdGVkIEtleSA8Uk5TNFBaMjZSUzRYSVRPRkFIWFk3MlZRQU9O\\nSlhXWkxBUExWV0pSNURRMzMzQko2SEgyMlVMREhIWVBCS1dSTkozTU5IWVhWVkE0\\\ + nSkpFRzZGVDI2WkFZTkMySzQ0QjVVRVpPRE9PWT0+iQI/BBMBCgApBQJbbWBiAhsv\\nBQkB4VFeBwsJCAcDAgEGFQgCCQoLBBYCAwECHgECF4AACgkQJARDGLfkpFMzEBAA\\\ + nk/gL5kIT1I9zEWy1dcV1eX1EI56J7lSg3Y+SH5N2hIrBIjdFKNlP3Chj2CS29Qyt\\nnL2qH4Ww9ONt5mPe6NskF0hszoH4MqYilcNeXXfnsm3PDatPzxhVav3Ulg8eR5eB\\\ + n5VgY31g2UEVhmv6AA/BAtZdsBOugS0id1w+wEE2GLe7Ddm+w5Qsyb1X/Ee4TFi+k\\npPToWlmaWLVy9LN4711TLzeeNJ7OMfnem14KMvYGEGgYygm7E5+XqVBskX7TYh7g\\\ + nLNaJ/T47BZtx8egLb3ScY05ObBVoGkCQel8TizalElvfhmlu+tr/REovuhW8u9Rs\\ndC36zvD5R36eK3HzGmXhtCv5I36tcG5hh67Wi7uxzI1iZHW/lN4d/zzgBSEVoONV\\\ + n4LVtfNUbWQqG28RjN3rvDhP0Zl+VrPB2WXn+el+nRp5zLgCQWczWoOiTRjPlpxEC\\nG4IEJsbuU2ggiamapIKZOWS5+wVUzpfw/nltW3xsIKIijUFUtrst/yPZcvC7RafJ\\\ + nUN65U4hRXnF8h+zHv8vwjqvB5IeuWncjQ08ynqGSxV4rtU08pH3dFzaNXynu6lU9\\n68QHhEElvyffzqu/B6MSOxyfOHSx3lrHeoeG6lMDLFhsiYLRxYfh5ea6q9IGY6dR\\\ + nUn97d32Xt/Y47Ws4z6awHtKeZw+SwxuUQ2Tu0AY5WVU=\\n=H3Lz\\n-----END PGP PUBLIC\ + \ KEY BLOCK-----\\n\", \n \"type\": \"PGP\"\n }, \n \"last_updated\"\ + : \"2018-08-10T09:52:40.480696Z\", \n \"number_of_documents\": 0, \n\ + \ \"number_of_messages\": 2, \n \"remove_star_url\": \"/api/v1/sources/a8c91c7b-a36d-43f8-930e-e955a77f3c44/remove_star\"\ + , \n \"replies_url\": \"/api/v1/sources/a8c91c7b-a36d-43f8-930e-e955a77f3c44/replies\"\ + , \n \"reply_url\": \"/api/v1/sources/a8c91c7b-a36d-43f8-930e-e955a77f3c44/replies\"\ + , \n \"submissions_url\": \"/api/v1/sources/a8c91c7b-a36d-43f8-930e-e955a77f3c44/submissions\"\ + , \n \"url\": \"/api/v1/sources/a8c91c7b-a36d-43f8-930e-e955a77f3c44\"\ + , \n \"uuid\": \"a8c91c7b-a36d-43f8-930e-e955a77f3c44\"\n }\n ]\n\ + }\n"} + headers: + Content-Length: ['5409'] + Content-Type: [application/json] + Date: ['Fri, 10 Aug 2018 09:53:07 GMT'] + Server: [Werkzeug/0.12.2 Python/2.7.6] + Set-Cookie: [js=eyJleHBpcmVzIjp7IiBkIjoiRnJpLCAxMCBBdWcgMjAxOCAxMTo1MzowNyBHTVQifX0.Dk7yAw.2_Iqf7RJ732alfyY8mc6W9bPW9U; + HttpOnly; Path=/] + status: {code: 200, message: OK} +- request: + body: null + headers: + Accept: [application/json] + Accept-Encoding: ['gzip, deflate'] + Authorization: [token eyJhbGciOiJIUzI1NiIsImV4cCI6MTUzMzkyMzU4NiwiaWF0IjoxNTMzODk0Nzg2fQ.eyJpZCI6MX0.LGxN6cLw-icCD-nuir4jzB4l6Fw44Sv3VERh6ykPzFw] + Connection: [keep-alive] + Content-Type: [application/json] + User-Agent: [python-requests/2.19.1] + method: GET + uri: http://localhost:8081/api/v1/sources/4baa4751-7c46-4d0a-a4a4-884a6f44609c/submissions + response: + body: {string: "{\n \"submissions\": [\n {\n \"download_url\": \"/api/v1/sources/4baa4751-7c46-4d0a-a4a4-884a6f44609c/submissions/ad14ca15-9039-4c1c-8dbf-470385381f93/download\"\ + , \n \"filename\": \"1-hard-shelled_cruet-msg.gpg\", \n \"is_read\"\ + : false, \n \"size\": 604, \n \"source_url\": \"/api/v1/sources/4baa4751-7c46-4d0a-a4a4-884a6f44609c\"\ + , \n \"submission_url\": \"/api/v1/sources/4baa4751-7c46-4d0a-a4a4-884a6f44609c/submissions/ad14ca15-9039-4c1c-8dbf-470385381f93\"\ + , \n \"uuid\": \"ad14ca15-9039-4c1c-8dbf-470385381f93\"\n }, \n \ + \ {\n \"download_url\": \"/api/v1/sources/4baa4751-7c46-4d0a-a4a4-884a6f44609c/submissions/2fd63768-0f6f-4b31-9a91-348e9311f9dd/download\"\ + , \n \"filename\": \"2-hard-shelled_cruet-msg.gpg\", \n \"is_read\"\ + : false, \n \"size\": 604, \n \"source_url\": \"/api/v1/sources/4baa4751-7c46-4d0a-a4a4-884a6f44609c\"\ + , \n \"submission_url\": \"/api/v1/sources/4baa4751-7c46-4d0a-a4a4-884a6f44609c/submissions/2fd63768-0f6f-4b31-9a91-348e9311f9dd\"\ + , \n \"uuid\": \"2fd63768-0f6f-4b31-9a91-348e9311f9dd\"\n }\n ]\n\ + }\n"} + headers: + Content-Length: ['1039'] + Content-Type: [application/json] + Date: ['Fri, 10 Aug 2018 09:53:07 GMT'] + Server: [Werkzeug/0.12.2 Python/2.7.6] + Set-Cookie: [js=eyJleHBpcmVzIjp7IiBkIjoiRnJpLCAxMCBBdWcgMjAxOCAxMTo1MzowNyBHTVQifX0.Dk7yAw.2_Iqf7RJ732alfyY8mc6W9bPW9U; + HttpOnly; Path=/] + status: {code: 200, message: OK} +- request: + body: null + headers: + Accept: [application/json] + Accept-Encoding: ['gzip, deflate'] + Authorization: [token eyJhbGciOiJIUzI1NiIsImV4cCI6MTUzMzkyMzU4NiwiaWF0IjoxNTMzODk0Nzg2fQ.eyJpZCI6MX0.LGxN6cLw-icCD-nuir4jzB4l6Fw44Sv3VERh6ykPzFw] + Connection: [keep-alive] + Content-Type: [application/json] + User-Agent: [python-requests/2.19.1] + method: GET + uri: http://localhost:8081/api/v1/sources/4baa4751-7c46-4d0a-a4a4-884a6f44609c/submissions/ad14ca15-9039-4c1c-8dbf-470385381f93 + response: + body: {string: "{\n \"download_url\": \"/api/v1/sources/4baa4751-7c46-4d0a-a4a4-884a6f44609c/submissions/ad14ca15-9039-4c1c-8dbf-470385381f93/download\"\ + , \n \"filename\": \"1-hard-shelled_cruet-msg.gpg\", \n \"is_read\": false,\ + \ \n \"size\": 604, \n \"source_url\": \"/api/v1/sources/4baa4751-7c46-4d0a-a4a4-884a6f44609c\"\ + , \n \"submission_url\": \"/api/v1/sources/4baa4751-7c46-4d0a-a4a4-884a6f44609c/submissions/ad14ca15-9039-4c1c-8dbf-470385381f93\"\ + , \n \"uuid\": \"ad14ca15-9039-4c1c-8dbf-470385381f93\"\n}\n"} + headers: + Content-Length: ['469'] + Content-Type: [application/json] + Date: ['Fri, 10 Aug 2018 09:53:07 GMT'] + Server: [Werkzeug/0.12.2 Python/2.7.6] + Set-Cookie: [js=eyJleHBpcmVzIjp7IiBkIjoiRnJpLCAxMCBBdWcgMjAxOCAxMTo1MzowNyBHTVQifX0.Dk7yAw.2_Iqf7RJ732alfyY8mc6W9bPW9U; + HttpOnly; Path=/] + status: {code: 200, message: OK} +version: 1 diff --git a/sdclientapi/__init__.py b/sdclientapi/__init__.py index 323afc4d1..fb9023224 100644 --- a/sdclientapi/__init__.py +++ b/sdclientapi/__init__.py @@ -365,7 +365,10 @@ def get_submission(self, submission: Submission) -> Submission: :param submission: Submission object we want to update. :returns: Updated submission object from the server. """ - url = self.server.rstrip("/") + submission.submission_url + source_uuid = submission.source_url.split("/")[-1] + url = self.server.rstrip("/") + "/api/v1/sources/{}/submissions/{}".format( + source_uuid, submission.uuid + ) try: res = requests.get(url, headers=self.auth_header) @@ -382,6 +385,18 @@ def get_submission(self, submission: Submission) -> Submission: return Submission(**data) + def get_submission_from_string(self, uuid: str, source_uuid: str) -> Submission: + """ + Returns the updated Submission object from the server. + + :param uuid: UUID of the Submission object. + :param source_uuid: UUID of the source. + :returns: Updated submission object from the server. + """ + s = Submission(uuid=uuid) + s.source_url = "/api/v1/sources/{}".format(source_uuid) + return self.get_submission(s) + def get_all_submissions(self) -> List[Submission]: """ Returns a list of Submission objects from the server. diff --git a/tests/test_api.py b/tests/test_api.py index 686fb39c6..e691d5843 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -94,6 +94,22 @@ def test_get_submissions(self): subs = self.api.get_submissions(s) self.assertEqual(len(subs), 2) + @vcr.use_cassette("data/test-get-submission.yml") + def test_get_submission(self): + s = self.api.get_sources()[0] + + subs = self.api.get_submissions(s) + sub = self.api.get_submission(subs[0]) + self.assertEqual(sub.filename, subs[0].filename) + + @vcr.use_cassette("data/test-get-submission.yml") + def test_get_submission_from_string(self): + s = self.api.get_sources()[0] + + subs = self.api.get_submissions(s) + sub = self.api.get_submission_from_string(subs[0].uuid, s.uuid) + self.assertEqual(sub.filename, subs[0].filename) + @vcr.use_cassette("data/test-get-wrong-submissions.yml") def test_get_wrong_submissions(self): s = self.api.get_sources()[0] From 22d049927d6833da76a1bb7a37cb99b72a9430f9 Mon Sep 17 00:00:00 2001 From: Kushal Das Date: Fri, 10 Aug 2018 18:08:54 +0530 Subject: [PATCH 4/4] Adds delete_submission_from_string method Also we have test case for the same. We need both the source, and submission uuid string values. --- data/test-delete-submission-from-string.yml | 164 ++++++++++++++++++++ sdclientapi/__init__.py | 20 ++- tests/test_api.py | 15 ++ 3 files changed, 198 insertions(+), 1 deletion(-) create mode 100644 data/test-delete-submission-from-string.yml diff --git a/data/test-delete-submission-from-string.yml b/data/test-delete-submission-from-string.yml new file mode 100644 index 000000000..f00c79199 --- /dev/null +++ b/data/test-delete-submission-from-string.yml @@ -0,0 +1,164 @@ +interactions: +- request: + body: null + headers: + Accept: [application/json] + Accept-Encoding: ['gzip, deflate'] + Authorization: [token eyJhbGciOiJIUzI1NiIsImV4cCI6MTUzMzkzMjk3MCwiaWF0IjoxNTMzOTA0MTcwfQ.eyJpZCI6MX0.DKawe5bPF0-nh6DeOb7FB-pL-7MvkT-pBeua6U1olP8] + Connection: [keep-alive] + Content-Type: [application/json] + User-Agent: [python-requests/2.19.1] + method: GET + uri: http://localhost:8081/api/v1/sources + response: + body: {string: "{\n \"sources\": [\n {\n \"add_star_url\": \"/api/v1/sources/b8764f7f-a066-4d62-8043-7dc62af021aa/add_star\"\ + , \n \"interaction_count\": 4, \n \"is_flagged\": false, \n \ + \ \"is_starred\": false, \n \"journalist_designation\": \"storied kohl\"\ + , \n \"key\": {\n \"public\": \"-----BEGIN PGP PUBLIC KEY BLOCK-----\\\ + n\\nmQINBFttgrMBEADJlA0VWoH1qM8ADbVb57UFAkLcmjS6Cmnipu6kAq3cuD02+cNT\\nEMIDwM30UEcN5DjAQqh6ItXa9ZTUcf5rAfzYS1oVFBIjSbQQddVxcVnHFqQhC96l\\\ + neZ0l2QywohN636BwhFn9bLFDhtOygwWzR8ekSE4Nr+XBWvJGvM4GG+huM+HPxwnf\\nI10fy0ODnVPSnN1EZjv8KojqRgcBdK6lUpP8tXBwVp+qJT4AO64J9AMwoXqGsmgn\\\ + nuMCk5K9mchpSKDrTYE5Qli1OXICfaFHafdm5RBNVCmUDxXqqgyDSUSnkwjz7/g/q\\nuzAJxgMmoy4EXpkNvMArlM10XP7w/0ijt6lrwbI1AsHQqn+FWG2fOs7wMGE0yhS+\\\ + nBu/Jjo6kGf3dkP4h5ptioUT6tgku/7wA4e4TomwI26QqXsAyjEiNvhq6x9AbqzO2\\nyzqMi/SGUGWuTDmQzESK59jJSSXWnVsVX90neeFwiuWiSniN4xhnnFvhGCTuscJF\\\ + n4w0c+JVxr58M8/YMnmXdWMSg/7Mt7xsutSy1Ym2lKbvTqtHB2GR+LSfUfTZcm3L9\\nUsGCvAwsIIrMSbagJCQJIaLDc2FhaTeIJNz8LrHQj0hElkyrenKPbVc6lSxdB2T/\\\ + nDmTuauqXIqWnqqVKPVViBi/3WdOYmr1deruND5X3LcUA9xkSfUi2gXDMkwARAQAB\\ntHxBdXRvZ2VuZXJhdGVkIEtleSA8WEVHSERDNk9SV05QVVhWSkZLUEMyU0haWkNV\\\ + nSjNISlVWQlI1QUc2RlBJWkRRUENDU0NVNDdETUFKRU1USk5GWVFKRlZFVFVWUVdH\\nU1RPR0M2NFFDUk1YQ01ZSDYyUUJGNldOSFhYWT0+iQI/BBMBCgApBQJbbYKzAhsv\\\ + nBQkB4S8NBwsJCAcDAgEGFQgCCQoLBBYCAwECHgECF4AACgkQIrDqYpiXlX/3fQ//\\nQ+syqKppyDKF6TF8kaNssXNaDRHm8ajQHVanXROUT8j6nj72Z+en6wnYGV5H1Gb8\\\ + nenpzmInPTMtdV0W4GdAgp+yV0/KVCsQrKBRGO0HDqnGNeBbby9qX0RUTPYwe+HGL\\nIFw0FSMMlwnSMytvh9rjBj5n3/n+YMb8MBVWGQceGvMZqjbRWcGmUpcRRsFuD36m\\\ + nIvuUhAOePw8MARr+T3PppJbUCpsM1cdB9hfeedoCgzBctRh8M3Vp7ihCQkfk9cvt\\nKkGQiQndaIaPtZi8ChX92pFkQoG+VWFEuAMoP+cVu+mpN/LpyZ1Hj16Vw+hToYd3\\\ + nPyvsMgWc1rB+tz7YHa0ZbGJCgU/armK7DHtnUQaznUPmPQtqcIMD1KFFcmb9O6pH\\neB+HMKmS6vZylYiGkLRWsmbC+m91weWMNgi5q0fu+XFYqtu66Tzaj39NUuFUUnys\\\ + n9XDd6QdQxwJmytFOjYB+7gLJn1OXOl7hzovklFY7x7YdpCKVNQ71QKqkbzM6qN13\\nEU/qLprjT2YI5WNfzU2ePHpbgpQlEOYQ2JUNFjZZ+a4ffNgGXpi7fgW3wrvsDIun\\\ + nwZPDSxzlVejxYuseCpxp9gat2coXGnNTInNHhExXXtaj7bqP7FVuya8Xec3BJ9yv\\n3KgNMRKBRy4J+AmGP5n7STAh+N8iQ3uGiIg0kzqCoxk=\\\ + n=AHZp\\n-----END PGP PUBLIC KEY BLOCK-----\\n\", \n \"type\": \"PGP\"\ + \n }, \n \"last_updated\": \"2018-08-10T12:19:00.992348Z\", \n \ + \ \"number_of_documents\": 0, \n \"number_of_messages\": 2, \n \ + \ \"remove_star_url\": \"/api/v1/sources/b8764f7f-a066-4d62-8043-7dc62af021aa/remove_star\"\ + , \n \"replies_url\": \"/api/v1/sources/b8764f7f-a066-4d62-8043-7dc62af021aa/replies\"\ + , \n \"reply_url\": \"/api/v1/sources/b8764f7f-a066-4d62-8043-7dc62af021aa/replies\"\ + , \n \"submissions_url\": \"/api/v1/sources/b8764f7f-a066-4d62-8043-7dc62af021aa/submissions\"\ + , \n \"url\": \"/api/v1/sources/b8764f7f-a066-4d62-8043-7dc62af021aa\"\ + , \n \"uuid\": \"b8764f7f-a066-4d62-8043-7dc62af021aa\"\n }, \n \ + \ {\n \"add_star_url\": \"/api/v1/sources/2caafcf4-0983-4e2a-9aba-f18146076849/add_star\"\ + , \n \"interaction_count\": 4, \n \"is_flagged\": false, \n \ + \ \"is_starred\": false, \n \"journalist_designation\": \"purifying\ + \ squeezer\", \n \"key\": {\n \"public\": \"-----BEGIN PGP PUBLIC\ + \ KEY BLOCK-----\\n\\nmQINBFttgroBEADL18oxabIYN62ADvH5ekkCr3G7ku5EYazxS4QXc7xUWmM16dOI\\\ + n1KuLs+Dtavqh3lW9NA22B2CnQHoGiAT/4X9Jbo+PA+NktjIIChXWPj6toN/QNL+l\\n9+BM1UUImqwextlG8txLsOVIu7LB071Zvbc1DLVoyKeZKu9S93fE5aJmUvn96N6Z\\\ + ngVVgBq4o4zTGrdeGbjUZWM5eyRNmiCOMnwVXlJT3IGzfXRqgrHepn0YT7k9DGXQm\\n2kbihWWZSHAR1R7/RjI7wiqB/U/n2isM6krTLgwras+8CoymSBPPf51k86NgybHf\\\ + ndMtQXEkFpaJseAV+rdso+wDt0Ml8mB57oNhlEo3lii7+ObGZ2Y/8ug0u9TYIGl8f\\nrbo6laJBF+qyOxuEZxpiApE2WcjcLToqjYzUOm361DE2rzrGtMz2ivgCqGcCpNWI\\\ + nc42L4bCwCutiWjOWZrRPpM3TchBtNFMXPMurBKfQrEXZaaWH55DmfxN6YZAEFAaU\\nguNPRd/t7FuUU6eQJ8JU7jPZXkvMAd8ThGU6xoLKjl+cfrUN9vf0JV1ZXWiUT40d\\\ + n1dJaxHgd2US+Uqk4ZGxEzNzkkEFxnSf7VeSXxjyavVD77P3a77Bbw/N/VdHidFjH\\n0SV8W6v5PrZbWwz8kan/9wmZlW8TdmVXoyGbE/Br/nAisdBAI3M5h0jsNwARAQAB\\\ + ntHxBdXRvZ2VuZXJhdGVkIEtleSA8WElaUFBCTkVNNFVISUtaT1dBUzVPUVNMQTRW\\nM1dVN1RCQUZUR0xYQkUzM0tZUVA2SDJQRUpCNlVSSlpKMjY1NlpHR1VIRkJSVFVY\\\ + nRFBHVFRWQVRLWDYzVlhQTzdDUFY0WEgyU0lNWT0+iQI/BBMBCgApBQJbbYK6Ahsv\\nBQkB4S8GBwsJCAcDAgEGFQgCCQoLBBYCAwECHgECF4AACgkQo/sjDcjNJ2PIAg//\\\ + nTVBZHBxqFdLDq78CekwBvMKPB2ahTnYdL1SbvJGsNIblPj8gHu7t+BFLpg9XZsrC\\nOUG3OSG4BKOw4127p3C+1VzLDI0xMvG935rCUGaZQ1s3Z48IY36HNDUU9otftKU4\\\ + nGaTCmnNq40HWtLun4tWqT+kiqXGxm8Qo4nV1iCtYxhLGMzt6AuP4BVDrARXh0nQr\\nd5ltq/CcrV2Ofw3MpwDjZXAnp6QCL/l8ZwTENfzd60uF5o2QAzZZ2+zSBv14BwYm\\\ + nxj1ohk0LF7zT5JZrgu5mC/kndMXlrF8LNhj3SCZhj8DvMgQcV9iH5SpKdsSSajFH\\nC2hRHm4Ys1CZ0clRBxWjNS85YIkqAP6WbiOMsXz6+MqlR46kZG3uT9zaW0m56pQ9\\\ + nw+02kWdBy/7GgFu9Ta53Mqrnv5u7dXHjLgLZO8SxQwCee2S+GiwlUp0pGzxpnjlD\\nH9p1WUXKkbKppvXiug6VI6xzqZ7OjHh+m5Qjz6Ea+Nv1fizvsPYetoACtFQdXsAj\\\ + n352cB3Df63Pj2LwsDp1VEYWEmTSEx7YY9gwNIrXakQgRcVusEtbReHLNZadaCe6E\\nLkpf4Mod2rXLJHpO0IgfxpBTdwV479dCi7vr0ZtVzg77S8Ssaq7uKzTdp1MMjBLD\\\ + nHF1E8pexGXxe5TB1s8XqsTKxkBBxB+zzxvNFhfnieW8=\\n=T9Jm\\n-----END PGP PUBLIC\ + \ KEY BLOCK-----\\n\", \n \"type\": \"PGP\"\n }, \n \"last_updated\"\ + : \"2018-08-10T12:19:12.147910Z\", \n \"number_of_documents\": 0, \n\ + \ \"number_of_messages\": 2, \n \"remove_star_url\": \"/api/v1/sources/2caafcf4-0983-4e2a-9aba-f18146076849/remove_star\"\ + , \n \"replies_url\": \"/api/v1/sources/2caafcf4-0983-4e2a-9aba-f18146076849/replies\"\ + , \n \"reply_url\": \"/api/v1/sources/2caafcf4-0983-4e2a-9aba-f18146076849/replies\"\ + , \n \"submissions_url\": \"/api/v1/sources/2caafcf4-0983-4e2a-9aba-f18146076849/submissions\"\ + , \n \"url\": \"/api/v1/sources/2caafcf4-0983-4e2a-9aba-f18146076849\"\ + , \n \"uuid\": \"2caafcf4-0983-4e2a-9aba-f18146076849\"\n }\n ]\n\ + }\n"} + headers: + Content-Length: ['5401'] + Content-Type: [application/json] + Date: ['Fri, 10 Aug 2018 12:29:30 GMT'] + Server: [Werkzeug/0.12.2 Python/2.7.6] + Set-Cookie: [js=eyJleHBpcmVzIjp7IiBkIjoiRnJpLCAxMCBBdWcgMjAxOCAxNDoyOTozMCBHTVQifX0.Dk8Wqg.7HzB7FOlg5fIt3kogTSRGUBUXUk; + HttpOnly; Path=/] + status: {code: 200, message: OK} +- request: + body: null + headers: + Accept: [application/json] + Accept-Encoding: ['gzip, deflate'] + Authorization: [token eyJhbGciOiJIUzI1NiIsImV4cCI6MTUzMzkzMjk3MCwiaWF0IjoxNTMzOTA0MTcwfQ.eyJpZCI6MX0.DKawe5bPF0-nh6DeOb7FB-pL-7MvkT-pBeua6U1olP8] + Connection: [keep-alive] + Content-Type: [application/json] + User-Agent: [python-requests/2.19.1] + method: GET + uri: http://localhost:8081/api/v1/sources/b8764f7f-a066-4d62-8043-7dc62af021aa/submissions + response: + body: {string: "{\n \"submissions\": [\n {\n \"download_url\": \"/api/v1/sources/b8764f7f-a066-4d62-8043-7dc62af021aa/submissions/aa641164-e646-428a-983c-fe8f7390994b/download\"\ + , \n \"filename\": \"1-storied_kohl-msg.gpg\", \n \"is_read\": false,\ + \ \n \"size\": 604, \n \"source_url\": \"/api/v1/sources/b8764f7f-a066-4d62-8043-7dc62af021aa\"\ + , \n \"submission_url\": \"/api/v1/sources/b8764f7f-a066-4d62-8043-7dc62af021aa/submissions/aa641164-e646-428a-983c-fe8f7390994b\"\ + , \n \"uuid\": \"aa641164-e646-428a-983c-fe8f7390994b\"\n }, \n \ + \ {\n \"download_url\": \"/api/v1/sources/b8764f7f-a066-4d62-8043-7dc62af021aa/submissions/4124cf62-2bc5-419b-86be-e00da5d84477/download\"\ + , \n \"filename\": \"2-storied_kohl-msg.gpg\", \n \"is_read\": false,\ + \ \n \"size\": 604, \n \"source_url\": \"/api/v1/sources/b8764f7f-a066-4d62-8043-7dc62af021aa\"\ + , \n \"submission_url\": \"/api/v1/sources/b8764f7f-a066-4d62-8043-7dc62af021aa/submissions/4124cf62-2bc5-419b-86be-e00da5d84477\"\ + , \n \"uuid\": \"4124cf62-2bc5-419b-86be-e00da5d84477\"\n }\n ]\n\ + }\n"} + headers: + Content-Length: ['1027'] + Content-Type: [application/json] + Date: ['Fri, 10 Aug 2018 12:29:30 GMT'] + Server: [Werkzeug/0.12.2 Python/2.7.6] + Set-Cookie: [js=eyJleHBpcmVzIjp7IiBkIjoiRnJpLCAxMCBBdWcgMjAxOCAxNDoyOTozMCBHTVQifX0.Dk8Wqg.7HzB7FOlg5fIt3kogTSRGUBUXUk; + HttpOnly; Path=/] + status: {code: 200, message: OK} +- request: + body: null + headers: + Accept: [application/json] + Accept-Encoding: ['gzip, deflate'] + Authorization: [token eyJhbGciOiJIUzI1NiIsImV4cCI6MTUzMzkzMjk3MCwiaWF0IjoxNTMzOTA0MTcwfQ.eyJpZCI6MX0.DKawe5bPF0-nh6DeOb7FB-pL-7MvkT-pBeua6U1olP8] + Connection: [keep-alive] + Content-Length: ['0'] + Content-Type: [application/json] + User-Agent: [python-requests/2.19.1] + method: DELETE + uri: http://localhost:8081/api/v1/sources/b8764f7f-a066-4d62-8043-7dc62af021aa/submissions/aa641164-e646-428a-983c-fe8f7390994b + response: + body: {string: "{\n \"message\": \"Submission deleted\"\n}\n"} + headers: + Content-Length: ['38'] + Content-Type: [application/json] + Date: ['Fri, 10 Aug 2018 12:29:30 GMT'] + Server: [Werkzeug/0.12.2 Python/2.7.6] + Set-Cookie: [js=eyJleHBpcmVzIjp7IiBkIjoiRnJpLCAxMCBBdWcgMjAxOCAxNDoyOTozMCBHTVQifX0.Dk8Wqg.7HzB7FOlg5fIt3kogTSRGUBUXUk; + HttpOnly; Path=/] + status: {code: 200, message: OK} +- request: + body: null + headers: + Accept: [application/json] + Accept-Encoding: ['gzip, deflate'] + Authorization: [token eyJhbGciOiJIUzI1NiIsImV4cCI6MTUzMzkzMjk3MCwiaWF0IjoxNTMzOTA0MTcwfQ.eyJpZCI6MX0.DKawe5bPF0-nh6DeOb7FB-pL-7MvkT-pBeua6U1olP8] + Connection: [keep-alive] + Content-Type: [application/json] + User-Agent: [python-requests/2.19.1] + method: GET + uri: http://localhost:8081/api/v1/submissions + response: + body: {string: "{\n \"submissions\": [\n {\n \"download_url\": \"/api/v1/sources/b8764f7f-a066-4d62-8043-7dc62af021aa/submissions/4124cf62-2bc5-419b-86be-e00da5d84477/download\"\ + , \n \"filename\": \"2-storied_kohl-msg.gpg\", \n \"is_read\": false,\ + \ \n \"size\": 604, \n \"source_url\": \"/api/v1/sources/b8764f7f-a066-4d62-8043-7dc62af021aa\"\ + , \n \"submission_url\": \"/api/v1/sources/b8764f7f-a066-4d62-8043-7dc62af021aa/submissions/4124cf62-2bc5-419b-86be-e00da5d84477\"\ + , \n \"uuid\": \"4124cf62-2bc5-419b-86be-e00da5d84477\"\n }, \n \ + \ {\n \"download_url\": \"/api/v1/sources/2caafcf4-0983-4e2a-9aba-f18146076849/submissions/a1af208a-cc47-407c-9a53-79a2ef7efe9a/download\"\ + , \n \"filename\": \"1-purifying_squeezer-msg.gpg\", \n \"is_read\"\ + : false, \n \"size\": 604, \n \"source_url\": \"/api/v1/sources/2caafcf4-0983-4e2a-9aba-f18146076849\"\ + , \n \"submission_url\": \"/api/v1/sources/2caafcf4-0983-4e2a-9aba-f18146076849/submissions/a1af208a-cc47-407c-9a53-79a2ef7efe9a\"\ + , \n \"uuid\": \"a1af208a-cc47-407c-9a53-79a2ef7efe9a\"\n }, \n \ + \ {\n \"download_url\": \"/api/v1/sources/2caafcf4-0983-4e2a-9aba-f18146076849/submissions/df94fe82-c582-4118-8fa2-1b81eca738b2/download\"\ + , \n \"filename\": \"2-purifying_squeezer-msg.gpg\", \n \"is_read\"\ + : false, \n \"size\": 604, \n \"source_url\": \"/api/v1/sources/2caafcf4-0983-4e2a-9aba-f18146076849\"\ + , \n \"submission_url\": \"/api/v1/sources/2caafcf4-0983-4e2a-9aba-f18146076849/submissions/df94fe82-c582-4118-8fa2-1b81eca738b2\"\ + , \n \"uuid\": \"df94fe82-c582-4118-8fa2-1b81eca738b2\"\n }\n ]\n\ + }\n"} + headers: + Content-Length: ['1540'] + Content-Type: [application/json] + Date: ['Fri, 10 Aug 2018 12:29:30 GMT'] + Server: [Werkzeug/0.12.2 Python/2.7.6] + Set-Cookie: [js=eyJleHBpcmVzIjp7IiBkIjoiRnJpLCAxMCBBdWcgMjAxOCAxNDoyOTozMCBHTVQifX0.Dk8Wqg.7HzB7FOlg5fIt3kogTSRGUBUXUk; + HttpOnly; Path=/] + status: {code: 200, message: OK} +version: 1 diff --git a/sdclientapi/__init__.py b/sdclientapi/__init__.py index fb9023224..081a83d87 100644 --- a/sdclientapi/__init__.py +++ b/sdclientapi/__init__.py @@ -430,7 +430,13 @@ def delete_submission(self, submission: Submission) -> bool: :param submission: The Submission object we want to delete in the server. :returns: True if successful, raises Error otherwise. """ - url = self.server.rstrip("/") + submission.submission_url + # Not using direct URL because this helps to use the same method + # from local submission (not fetched from server) objects. + # See the *from_string for an example. + source_uuid = submission.source_url.split("/")[-1] + url = self.server.rstrip("/") + "/api/v1/sources/{}/submissions/{}".format( + source_uuid, submission.uuid + ) try: res = requests.delete(url, headers=self.auth_header) @@ -450,6 +456,18 @@ def delete_submission(self, submission: Submission) -> bool: # We should never reach here return False + def delete_submission_from_string(self, uuid: str, source_uuid: str) -> bool: + """ + Deletes a given Submission based on uuids from the server. + + :param uuid: UUID of the Submission object. + :param source_uuid: UUID of the source. + :returns: Updated submission object from the server. + """ + s = Submission(uuid=uuid) + s.source_url = "/api/v1/sources/{}".format(source_uuid) + return self.delete_submission(s) + def download_submission(self, submission: Submission, path: str) -> Tuple[str, str]: """ Returns a tuple of sha256sum and file path for a given Submission object. This method diff --git a/tests/test_api.py b/tests/test_api.py index e691d5843..7be956076 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -160,6 +160,21 @@ def test_delete_submission(self): for s in new_subs: self.assertNotEqual(s.uuid, subs[0].uuid) + @vcr.use_cassette("data/test-delete-submission-from-string.yml") + def test_delete_submission_from_string(self): + s = self.api.get_sources()[0] + + subs = self.api.get_submissions(s) + + self.assertTrue(self.api.delete_submission(subs[0])) + new_subs = self.api.get_all_submissions() + # We now should have 3 submissions + self.assertEqual(len(new_subs), 3) + + # Let us make sure that sub[0] is not there + for s in new_subs: + self.assertNotEqual(s.uuid, subs[0].uuid) + @vcr.use_cassette("data/test-get-current-user.yml") def test_get_current_user(self): user = self.api.get_current_user()