From a731f748d933445382630ae6e2adfe3f75400c84 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gina=20H=C3=A4u=C3=9Fge?= Date: Fri, 20 Nov 2015 10:02:06 +0100 Subject: [PATCH] Moved existing hidden file checks to utilize octoprint.util.is_hidden_path --- src/octoprint/filemanager/storage.py | 6 ++++-- src/octoprint/printer/profile.py | 4 ++-- src/octoprint/server/__init__.py | 2 +- src/octoprint/slicing/__init__.py | 3 ++- src/octoprint/util/__init__.py | 12 ++++++++++-- tests/util/test_file_helpers.py | 22 +++++++++++++--------- 6 files changed, 32 insertions(+), 17 deletions(-) diff --git a/src/octoprint/filemanager/storage.py b/src/octoprint/filemanager/storage.py index 1fe59e35..6a2378dd 100644 --- a/src/octoprint/filemanager/storage.py +++ b/src/octoprint/filemanager/storage.py @@ -13,6 +13,8 @@ import tempfile import octoprint.filemanager +from octoprint.util import is_hidden_path + class StorageInterface(object): """ Interface of storage adapters for OctoPrint. @@ -357,7 +359,7 @@ class LocalFileStorage(StorageInterface): if not metadata: metadata = dict() for entry in os.listdir(path): - if entry.startswith(".") or not octoprint.filemanager.valid_file_type(entry): + if is_hidden_path(entry) or not octoprint.filemanager.valid_file_type(entry): continue absolute_path = os.path.join(path, entry) @@ -887,7 +889,7 @@ class LocalFileStorage(StorageInterface): result = dict() for entry in os.listdir(path): - if entry.startswith("."): + if is_hidden_path(entry): # no hidden files and folders continue diff --git a/src/octoprint/printer/profile.py b/src/octoprint/printer/profile.py index 700aef07..f46d90bf 100644 --- a/src/octoprint/printer/profile.py +++ b/src/octoprint/printer/profile.py @@ -12,7 +12,7 @@ import re import logging from octoprint.settings import settings -from octoprint.util import dict_merge, dict_sanitize, dict_contains_keys +from octoprint.util import dict_merge, dict_sanitize, dict_contains_keys, is_hidden_path class SaveError(Exception): pass @@ -289,7 +289,7 @@ class PrinterProfileManager(object): def _load_all_identifiers(self): results = dict(_default=None) for entry in os.listdir(self._folder): - if entry.startswith(".") or not entry.endswith(".profile") or entry == "_default.profile": + if is_hidden_path(entry) or not entry.endswith(".profile") or entry == "_default.profile": continue path = os.path.join(self._folder, entry) diff --git a/src/octoprint/server/__init__.py b/src/octoprint/server/__init__.py index a4ecc972..643e32cc 100644 --- a/src/octoprint/server/__init__.py +++ b/src/octoprint/server/__init__.py @@ -342,7 +342,7 @@ class Server(): ) additional_mime_types=dict(mime_type_guesser=mime_type_guesser) admin_validator = dict(access_validation=util.tornado.access_validation_factory(app, loginManager, util.flask.user_validator)) - no_hidden_files_validator = dict(path_validation=util.tornado.path_validation_factory(lambda path: not os.path.basename(path).startswith("."), status_code=404)) + no_hidden_files_validator = dict(path_validation=util.tornado.path_validation_factory(lambda path: not octoprint.util.is_hidden_path(path), status_code=404)) def joined_dict(*dicts): if not len(dicts): diff --git a/src/octoprint/slicing/__init__.py b/src/octoprint/slicing/__init__.py index 84e2a6c5..58eb5de5 100644 --- a/src/octoprint/slicing/__init__.py +++ b/src/octoprint/slicing/__init__.py @@ -22,6 +22,7 @@ __copyright__ = "Copyright (C) 2014 The OctoPrint Project - Released under terms import os import octoprint.plugin import octoprint.events +import octoprint.util from octoprint.settings import settings import logging @@ -478,7 +479,7 @@ class SlicingManager(object): profiles = dict() slicer_profile_path = self.get_slicer_profile_path(slicer) for entry in os.listdir(slicer_profile_path): - if not entry.endswith(".profile") or entry.startswith("."): + if not entry.endswith(".profile") or octoprint.util.is_hidden_path(entry): # we are only interested in profiles and no hidden files continue diff --git a/src/octoprint/util/__init__.py b/src/octoprint/util/__init__.py index fa8d42ff..2174f4cf 100644 --- a/src/octoprint/util/__init__.py +++ b/src/octoprint/util/__init__.py @@ -615,19 +615,27 @@ def bom_aware_open(filename, encoding="ascii", mode="r", **kwargs): def is_hidden_path(path): + if path is None: + # we define a None path as not hidden here + return False + filename = os.path.basename(path) if filename.startswith("."): + # filenames starting with a . are hidden return True if sys.platform == "win32": + # if we are running on windows we also try to read the hidden file + # attribute via the windows api try: import ctypes attrs = ctypes.windll.kernel32.GetFileAttributesW(unicode(path)) - assert attrs != -1 - return bool(attrs & 2) + assert attrs != -1 # INVALID_FILE_ATTRIBUTES == -1 + return bool(attrs & 2) # FILE_ATTRIBUTE_HIDDEN == 2 except (AttributeError, AssertionError): pass + # if we reach that point, the path is not hidden return False diff --git a/tests/util/test_file_helpers.py b/tests/util/test_file_helpers.py index bc82fa60..a39b2853 100644 --- a/tests/util/test_file_helpers.py +++ b/tests/util/test_file_helpers.py @@ -7,6 +7,8 @@ __copyright__ = "Copyright (C) 2015 The OctoPrint Project - Released under terms import unittest import mock import os +import ddt +import sys import octoprint.util @@ -165,6 +167,8 @@ class TestAtomicWrite(unittest.TestCase): mock_file.close.assert_called_once_with() mock_move.assert_called_once_with("tempfile.tmp", "somefile.yaml") + +@ddt.ddt class IsHiddenPathTest(unittest.TestCase): def setUp(self): @@ -192,12 +196,12 @@ class IsHiddenPathTest(unittest.TestCase): import shutil shutil.rmtree(self.basepath) - def test_is_hidden_path(self): - self.assertFalse(octoprint.util.is_hidden_path(self.path_always_visible)) - self.assertTrue(octoprint.util.is_hidden_path(self.path_always_hidden)) - - import sys - if sys.platform == "win32": - self.assertTrue(octoprint.util.is_hidden_path(self.path_hidden_on_windows)) - else: - self.assertFalse(octoprint.util.is_hidden_path(self.path_hidden_on_windows)) + @ddt.data( + (None, False), + ("path_always_visible", False), + ("path_always_hidden", True), + ("path_hidden_on_windows", sys.platform == "win32") + ) + @ddt.unpack + def test_is_hidden_path(self, path_id, expected): + self.assertEqual(octoprint.util.is_hidden_path(getattr(self, path_id)), expected)