Publish Vulpes Preview 15 sources for desktop, Android and Tundra

Share Gaia assets and adapters, keep private profiles and development documents local, and update both public READMEs.
This commit is contained in:
OverSu 2026-09-30 23:13:03 +02:00
commit b38dea0597
25901 changed files with 9982925 additions and 369 deletions

View file

@ -0,0 +1,174 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
from abc import ABCMeta, abstractmethod
import os
import shutil
import mozlog
class GaiaFileManager(object):
"""Abstract file manager for Gaia."""
__metaclass__ = ABCMeta
def __init__(self, device, log_level=mozlog.unstructured.ERROR):
self._logger = mozlog.unstructured.getLogger('GaiaFileManager')
self._logger.setLevel(log_level)
self.device = device
@abstractmethod
def copy_file(self, source, destination):
"""Copy a file."""
@abstractmethod
def dir_exists(self, path):
"""Return true if path exists and is a directory."""
return
def duplicate_file(self, path, count):
"""Create duplicates of a file on the system and remove original."""
original = path
path, sep, filename = path.rpartition('/')
# We copy the file we've just created rather than pushing it
# multiple times, which would be much slower.
for i in range(1, count + 1):
# Make the remote filename unique by including an index
if '.' in filename:
indexed_filename = '_%d.'.join(iter(
filename.rsplit('.', 1))) % i
else:
indexed_filename = '%s_%d' % (filename, i)
duplicate = '/'.join([path, indexed_filename])
self.copy_file(original, duplicate)
self.remove(original)
@abstractmethod
def file_exists(self, path):
"""Return true if path exists and is a file."""
return
@abstractmethod
def list_items(self, path):
"""List items in path."""
return
@abstractmethod
def make_dirs(self, filename):
"""Make directory structure."""
@abstractmethod
def pull_file(self, path):
"""Returns contents of file."""
@abstractmethod
def push_file(self, local_path, remote_path=None, count=1):
"""Push a file to the system."""
@abstractmethod
def remove(self, path):
"""Remove file or directory."""
class GaiaDeviceFileManager(GaiaFileManager):
"""File manager for Gaia instance running on a B2G device or emulator."""
def copy_file(self, source, destination):
self._logger.debug('Copying: %s to: %s' % (source, destination))
self.device.manager.copyTree(source, destination)
def dir_exists(self, path):
self._logger.debug('Checking for existance of directory: %s' % path)
return self.device.manager.dirExists(path)
def file_exists(self, path):
self._logger.debug('Checking for existance of file: %s' % path)
return self.device.manager.fileExists(path)
def list_items(self, path):
self._logger.debug('Listing items in: %s' % path)
return self.device.manager.listFiles(path)
def make_dirs(self, filename):
self.device.manager.mkDirs(filename)
def pull_file(self, path):
return self.device.manager.pullFile(path)
def push_file(self, local_path, remote_path=None, count=1):
# If remote path is not specified, use the storage path
remote_path = remote_path or self.device.storage_path
filename = local_path.rpartition(os.path.sep)[-1]
remote_file = '/'.join([remote_path, filename])
self.make_dirs(remote_file)
self.device.manager.pushFile(local_path, remote_file)
if count > 1:
self.duplicate_file(remote_file, count)
def remove(self, path):
self._logger.debug('Removing: %s' % path)
self.device.manager.removeDir(path)
class GaiaLocalFileManager(GaiaFileManager):
"""File manager for Gaia instance running locally such as desktop B2G."""
def copy_file(self, source, destination):
source = os.path.normpath(source)
destination = os.path.normpath(destination)
self._logger.debug('Copying: %s to: %s' % (source, destination))
shutil.copy(source, destination)
def dir_exists(self, path):
path = os.path.normpath(path)
self._logger.debug('Checking for existance of directory: %s' % path)
return os.path.isdir(path)
def file_exists(self, path):
path = os.path.normpath(path)
self._logger.debug('Checking for existance of file: %s' % path)
return os.path.isfile(path)
def list_items(self, path):
path = os.path.normpath(path)
self._logger.debug('Listing items in: %s' % path)
return os.listdir(path)
def make_dirs(self, filename):
filename = os.path.normpath(filename)
containing = os.path.dirname(filename)
if not os.path.isdir(containing):
self._logger.debug('Making path: %s' % containing)
os.makedirs(containing)
def pull_file(self, path):
with open(path) as f:
return f.read()
def push_file(self, local_path, remote_path=None, count=1):
# If remote path is not specified, use the storage path
remote_path = remote_path or self.device.storage_path
filename = local_path.rpartition(os.path.sep)[-1]
remote_file = '/'.join([remote_path, filename])
self.make_dirs(remote_file)
path = os.path.normpath(remote_file)
if os.path.isdir(path):
raise Exception('Attempted to push a file (%s) to a directory '
'(%s)!' % (local_path, path))
if not os.access(local_path, os.F_OK):
raise Exception('File not found: %s' % local_path)
self._logger.debug('Pushing: %s to: %s' % (local_path, path))
self.copy_file(local_path, path)
if count > 1:
self.duplicate_file(remote_file, count)
def remove(self, path):
path = os.path.normpath(path)
if os.path.isfile(path):
self._logger.debug('Removing file: %s' % path)
os.remove(path)
elif os.path.isdir(path):
self._logger.debug('Removing directory: %s' % path)
shutil.rmtree(path)