about summary refs log tree commit diff stats
path: root/js/inknswitch/sw.js
blob: 4a63871533ac57b2e88b10cc62fa1370e6a0e374 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
self.addEventListener('install', function(event) {
    event.waitUntil(
      caches.open('inknswitch').then(function(cache) {
        return cache.addAll([
          './index.html',
          './ink.js',
          './android-icon-36x36.png',
          './android-icon-48x48.png',
          './android-icon-72x72.png',
          './android-icon-96x96.png',
          './android-icon-144x144.png',
          './android-icon-192x192.png',
          './apple-icon-57x57.png',
          './apple-icon-60x60.png',
          './apple-icon-72x72.png',
          './apple-icon-76x76.png',
          './apple-icon-114x114.png',
          './apple-icon-120x120.png',
          './apple-icon-144x144.png',
          './apple-icon-152x152.png',
          './apple-icon-180x180.png',
          './apple-icon-precomposed.png',
          './apple-icon.png',
        ]);
      })
    );
  });
  
  self.addEventListener('fetch', function(event) {
    event.respondWith(
      caches.match(event.request).then(function(response) {
        return response || fetch(event.request);
      })
    );
  });
d } /* Name.Constant */ .highlight .nd { color: #555555 } /* Name.Decorator */ .highlight .ne { color: #bb0066; font-weight: bold } /* Name.Exception */ .highlight .nf { color: #0066bb; font-weight: bold } /* Name.Function */ .highlight .nl { color: #336699; font-style: italic } /* Name.Label */ .highlight .nn { color: #bb0066; font-weight: bold } /* Name.Namespace */ .highlight .py { color: #336699; font-weight: bold } /* Name.Property */ .highlight .nt { color: #bb0066; font-weight: bold } /* Name.Tag */ .highlight .nv { color: #336699 } /* Name.Variable */ .highlight .ow { color: #008800 } /* Operator.Word */ .highlight .w { color: #bbbbbb } /* Text.Whitespace */ .highlight .mb { color: #0000DD; font-weight: bold } /* Literal.Number.Bin */ .highlight .mf { color: #0000DD; font-weight: bold } /* Literal.Number.Float */ .highlight .mh { color: #0000DD; font-weight: bold } /* Literal.Number.Hex */ .highlight .mi { color: #0000DD; font-weight: bold } /* Literal.Number.Integer */ .highlight .mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */ .highlight .sa { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Affix */ .highlight .sb { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Backtick */ .highlight .sc { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Char */ .highlight .dl { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Delimiter */ .highlight .sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */ .highlight .s2 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Double */ .highlight .se { color: #0044dd; background-color: #fff0f0 } /* Literal.String.Escape */ .highlight .sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */ .highlight .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */ .highlight .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */ .highlight .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */ .highlight .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */ .highlight .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */ .highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */ .highlight .fm { color: #0066bb; font-weight: bold } /* Name.Function.Magic */ .highlight .vc { color: #336699 } /* Name.Variable.Class */ .highlight .vg { color: #dd7700 } /* Name.Variable.Global */ .highlight .vi { color: #3333bb } /* Name.Variable.Instance */ .highlight .vm { color: #336699 } /* Name.Variable.Magic */ .highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */
# Copyright (C) 2009, 2010  Roman Zimbelmann <romanz@lavabit.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

CONTAINER_EXTENSIONS = 'rar zip tar gz bz bz2 tgz 7z iso cab'.split()
DOCUMENT_EXTENSIONS = 'pdf doc ppt odt'.split()
DOCUMENT_BASENAMES = 'README TODO LICENSE COPYING INSTALL'.split()

import time
from . import T_FILE, T_DIRECTORY, T_UNKNOWN, T_NONEXISTANT, BAD_INFO
from ranger.shared import MimeTypeAware, FileManagerAware
from ranger.ext.shell_escape import shell_escape

class FileSystemObject(MimeTypeAware, FileManagerAware):
	is_file = False
	is_directory = False
	content_loaded = False
	force_load = False
	path = None
	basename = None
	basename_lower = None
	_shell_escaped_basename = None
	_filetype = None
	dirname = None
	extension = None
	exists = False
	accessible = False
	marked = False
	tagged = False
	loaded = False
	runnable = False
	islink = False
	readlink = None
	stat = None
	infostring = None
	permissions = None
	type = T_UNKNOWN
	size = 0

	last_used = None

	stopped = False

	video = False
	image = False
	audio = False
	media = False
	document = False
	container = False
	mimetype_tuple = ()

	def __init__(self, path):
		MimeTypeAware.__init__(self)
		if type(self) == FileSystemObject:
			raise TypeError("Cannot initialize abstract class FileSystemObject")

		from os.path import abspath, basename, dirname, realpath

		path = abspath(path)
		self.path = path
		self.basename = basename(path)
		self.basename_lower = self.basename.lower()
		self.dirname = dirname(path)
		self.realpath = realpath(path)

		try:
			self.extension = self.basename[self.basename.rindex('.') + 1:].lower()
		except ValueError:
			self.extension = None

		self.set_mimetype()
		self.use()

	def __repr__(self):
		return "<{0} {1}>".format(self.__class__.__name__, self.path)

	@property
	def shell_escaped_basename(self):
		if self._shell_escaped_basename is None:
			self._shell_escaped_basename = shell_escape(self.basename)
		return self._shell_escaped_basename

	@property
	def filetype(self):
		if self._filetype is None:
			import subprocess
			try:
				got = subprocess.Popen(["file", '-Lb', '--mime-type',\
						self.path], stdout=subprocess.PIPE).communicate()[0]
			except OSError:
				self._filetype = ''
			else:
				self._filetype = got
		return self._filetype

	def get_description(self):
		return "Loading " + str(self)

	def __str__(self):
		"""returns a string containing the absolute path"""
		return str(self.path)

	def use(self):
		"""mark the filesystem-object as used at the current time"""
		self.last_used = time.time()

	def is_older_than(self, seconds):
		"""returns whether this object wasn't use()d in the last n seconds"""
		if seconds < 0:
			return True
		return self.last_used + seconds < time.time()

	def set_mimetype(self):
		"""assign attributes such as self.video according to the mimetype"""
		self.mimetype = self.mimetypes.guess_type(self.basename, False)[0]
		if self.mimetype is None:
			self.mimetype = ''

		self.video = self.mimetype.startswith('video')
		self.image = self.mimetype.startswith('image')
		self.audio = self.mimetype.startswith('audio')
		self.media = self.video or self.image or self.audio
		self.document = self.mimetype.startswith('text') \
				or (self.extension in DOCUMENT_EXTENSIONS) \
				or (self.basename in DOCUMENT_BASENAMES)
		self.container = self.extension in CONTAINER_EXTENSIONS

		keys = ('video', 'audio', 'image', 'media', 'document', 'container')
		self.mimetype_tuple = tuple(key for key in keys if getattr(self, key))

		if self.mimetype == '':
			self.mimetype = None

	def mark(self, boolean):
		directory = self.env.get_directory(self.dirname)
		directory.mark_item(self)

	def _mark(self, boolean):
		"""Called by directory.mark_item() and similar functions"""
		self.marked = bool(boolean)

	def load(self):
		"""
		reads useful information about the filesystem-object from the
		filesystem and caches it for later use
		"""
		import os
		import stat
		from ranger.ext.human_readable import human_readable

		self.loaded = True

		try:
			self.stat = os.lstat(self.path)
		except OSError:
			self.stat = None
			self.islink = False
			self.accessible = False
		else:
			self.islink = stat.S_ISLNK(self.stat.st_mode)
			self.accessible = True

		if self.accessible and os.access(self.path, os.F_OK):
			self.exists = True
			self.accessible = True

			if os.path.isdir(self.path):
				self.type = T_DIRECTORY
				try:
					self.size = len(os.listdir(self.path))
					self.infostring = ' %d' % self.size
					self.runnable = True
				except OSError:
					self.infostring = BAD_INFO
					self.runnable = False
					self.accessible = False
			elif os.path.isfile(self.path):
				self.type = T_FILE
				self.size = self.stat.st_size
				self.infostring = ' ' + human_readable(self.stat.st_size)
			else:
				self.type = T_UNKNOWN
				self.infostring = None

		else:
			if self.islink:
				self.infostring = '->'
			else:
				self.infostring = None
			self.type = T_NONEXISTANT
			self.exists = False
			self.runnable = False

		if self.islink:
			self.readlink = os.readlink(self.path)

	def get_permission_string(self):
		if self.permissions is not None:
			return self.permissions

		if self.accessible is False:
			return '----------'

		import stat
		mode = self.stat.st_mode

		if stat.S_ISDIR(mode):
			perms = ['d']
		elif stat.S_ISLNK(mode):
			perms = ['l']
		else:
			perms = ['-']

		for who in ("USR", "GRP", "OTH"):
			for what in "RWX":
				if mode & getattr(stat, "S_I" + what + who):
					perms.append(what.lower())
				else:
					perms.append('-')

		self.permissions = ''.join(perms)
		return self.permissions

	def load_once(self):
		"""calls load() if it has not been called at least once yet"""
		if not self.loaded:
			self.load()
			return True
		return False

	def go(self):
		"""enter the directory if the filemanager is running"""
		if self.fm:
			return self.fm.enter_dir(self.path)
		return False

	def load_if_outdated(self):
		"""
		Calls load() if the currently cached information is outdated
		or nonexistant.
		"""
		if self.load_once(): return True

		import os
		try:
			real_mtime = os.lstat(self.path).st_mtime
		except OSError:
			real_mtime = None
		if self.stat:
			cached_mtime = self.stat.st_mtime
		else:
			cached_mtime = 0

		if real_mtime != cached_mtime:
			self.load()
			return True
		return False