<commit_before>#!/usr/bin/env python
#-*- coding: utf-8 -*-

#This software is distributed under the Creative Commons license (CC0) version 1.0. A copy of this license should have been distributed with this software.
#The license can also be read online: <https://creativecommons.org/publicdomain/zero/1.0/>. If this online license differs from the license provided with this software, the license provided with this software should be applied.

"""
An implementation of persistent storage that reads and writes from the hard
drive.

All of these operations are explicitly atomic. This atomicity depends on the
operating system in some part, but all of the supported operating systems
(Windows, Linux) ensure that this is possible. Not all cases of concurrent
reading and writing can be accounted for, however. In particular, if a foreign
application writes directly in the file this will not be accounted for. When
dealing only with other instances of the same application, these functions
should behave atomically.
"""

import shutil #For the move function.
import os #To delete files, get modification times and flush data to files.
import urllib.parse #To get the scheme from a URI.

import localstorage.atomic_write_stream #To implement atomic writing.

def can_read(uri):
	"""
	Determines if this plug-in could read from a URI like the one specified.

	This determination is purely made on the URI, not on the actual file system.
	It can read from the URI if the URI uses the file scheme and is not a
	directory.

	:param uri: An absolute URI.
	:return: ``True`` if this plug-in can read from the specified URI, or
	``False`` if it can't.
	"""
	if uri is None:
		raise ValueError("Provided URI is None.")
	try:
		parsed = urllib.parse.urlparse(uri)
	except ValueError: #Badly-formed IPv6 address.
		return False #We don't care. We can only read locally anyway.

	if parsed.scheme != "file": #Can only read from file names.
		return False
	if parsed.path and parsed.path[-1] != "/": #Must have a file name, not a directory.
		return False
	return True

def can_write(uri):
	"""
	Determines if this plug-in could write to a URI like the one specified.

	This determination is purely made on the URI, not on the actual file system.
	It can write to the URI if the URI uses the file scheme.

	:param uri: An absolute URI.
	:return: ``True`` if this plug-in can write to the specified URI, or
	``False`` if it can't.
	"""
	if uri is None:
		raise ValueError("Provided URI is None.")
	try:
		return urllib.parse.urlparse(uri).scheme == "file" #Can only write to file schemes.
	except ValueError: #Badly-formed IPv6 address.
		return False #We don't care. We can only write locally anyway.

def delete(uri):
	"""
	Deletes the resource at the specified location.

	:param uri: The location of the resource to delete.
	:raises IOError: The file could not be deleted.
	"""
	os.remove(_uri_to_path(uri))

def exists(uri):
	"""
	Checks if the specified resource exists.

	:param uri: The location of the resource to check for.
	:return: ``True`` if the file exists, or ``False`` if it doesn't.
	:raises IOError: The existence check could not be performed.<commit_msg>Make can_write re-use can_read code<commit_after>#!/usr/bin/env python
#-*- coding: utf-8 -*-

#This software is distributed under the Creative Commons license (CC0) version 1.0. A copy of this license should have been distributed with this software.
#The license can also be read online: <https://creativecommons.org/publicdomain/zero/1.0/>. If this online license differs from the license provided with this software, the license provided with this software should be applied.

"""
An implementation of persistent storage that reads and writes from the hard
drive.

All of these operations are explicitly atomic. This atomicity depends on the
operating system in some part, but all of the supported operating systems
(Windows, Linux) ensure that this is possible. Not all cases of concurrent
reading and writing can be accounted for, however. In particular, if a foreign
application writes directly in the file this will not be accounted for. When
dealing only with other instances of the same application, these functions
should behave atomically.
"""

import shutil #For the move function.
import os #To delete files, get modification times and flush data to files.
import urllib.parse #To get the scheme from a URI.

import localstorage.atomic_write_stream #To implement atomic writing.

def can_read(uri):
	"""
	Determines if this plug-in could read from a URI like the one specified.

	This determination is purely made on the URI, not on the actual file system.
	It can read from the URI if the URI uses the file scheme and is not a
	directory.

	:param uri: An absolute URI.
	:return: ``True`` if this plug-in can read from the specified URI, or
	``False`` if it can't.
	"""
	if uri is None:
		raise ValueError("Provided URI is None.")
	try:
		parsed = urllib.parse.urlparse(uri)
	except ValueError: #Badly-formed IPv6 address.
		return False #We don't care. We can only read locally anyway.

	if parsed.scheme != "file": #Can only read from file names.
		return False
	if parsed.path and parsed.path[-1] != "/": #Must have a file name, not a directory.
		return False
	return True

def can_write(uri):
	"""
	Determines if this plug-in could write to a URI like the one specified.

	This determination is purely made on the URI, not on the actual file system.
	It can write to the URI if the URI uses the file scheme and is not a
	cirectory.

	:param uri: An absolute URI.
	:return: ``True`` if this plug-in can write to the specified URI, or
	``False`` if it can't.
	"""
	return can_read(uri) #We can write all URIs that we can read from.

def delete(uri):
	"""
	Deletes the resource at the specified location.

	:param uri: The location of the resource to delete.
	:raises IOError: The file could not be deleted.
	"""
	os.remove(_uri_to_path(uri))

def exists(uri):
	"""
	Checks if the specified resource exists.

	:param uri: The location of the resource to check for.
	:return: ``True`` if the file exists, or ``False`` if it doesn't.
	:raises IOError: The existence check could not be performed.
{'fraction_non_alphanumeric': 0.07633711507293355, 'fraction_numerical': 0.0027552674230145865, 'mean_word_length': 4.0252442996742674, 'pattern_counts': {'":': 4, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2264745', 'n_tokens_mistral': 1749, 'n_tokens_neox': 1693, 'n_words': 917}