diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..8b964eb --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,44 @@ +name: CI +on: + pull_request: + push: + branches: [master] + +jobs: + tests: + name: tests / ${{ matrix.os }} / ${{ matrix.python-version }} + runs-on: ${{ matrix.os }}-latest + + strategy: + matrix: + os: [Windows, Ubuntu, MacOS] + python-version: [3.6, 3.7, 3.8, 3.9] + include: + # Only run PyPy jobs, on Ubuntu. + - os: Ubuntu + python-version: pypy3 + + steps: + - uses: actions/checkout@v2 + + # Get Python to test against + - uses: actions/setup-python@v2 + with: + python-version: ${{ matrix.python-version }} + + # Setup pip's cache + - name: Save date (for cache) + id: date + run: echo "::set-output name=date::$(date +%F)" + - name: Save pip cache dir + id: pip-cache-dir + run: echo "::set-output name=dir::$(pip cache dir)" + - name: pip cache + uses: actions/cache@v1 + with: + path: ${{ steps.pip-cache-dir.outputs.dir }} + key: pip-v1-${{ runner.os }}-${{ steps.date.outputs.date }} + restore-keys: pip-v1-${{ runner.os }} + + - run: pip install nox + - run: nox -s test-${{ matrix.python-version }} diff --git a/CHANGES.rst b/CHANGES.rst index 10eed20..11f7c70 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -3,6 +3,14 @@ Changelog The full list of changes between each Python LiveReload release. +Version 3.0.0 +------------- + +*unreleased* + +1. Drop support for Python < 3.6. + + Version 2.6.3 ------------- diff --git a/LICENSE b/LICENSE index 16fd97b..b525206 100644 --- a/LICENSE +++ b/LICENSE @@ -1,3 +1,4 @@ +Copyright (c) 2021, Pradyun Gedam Copyright (c) 2012-2015, Hsiaoming Yang Redistribution and use in source and binary forms, with or without diff --git a/MANIFEST.in b/MANIFEST.in deleted file mode 100644 index 2d661dd..0000000 --- a/MANIFEST.in +++ /dev/null @@ -1,3 +0,0 @@ -include livereload/vendors/livereload.js -include LICENSE -include README.rst diff --git a/Makefile b/Makefile deleted file mode 100644 index fa27900..0000000 --- a/Makefile +++ /dev/null @@ -1,28 +0,0 @@ -.PHONY: clean-pyc clean-build docs test coverage - -clean: clean-build clean-pyc - - -clean-build: - rm -fr build/ - rm -fr dist/ - rm -fr *.egg-info - - -clean-pyc: - find . -name '*.pyc' -exec rm -f {} + - find . -name '*.pyo' -exec rm -f {} + - find . -name '*~' -exec rm -f {} + - -install: - python3 setup.py install - -docs: - $(MAKE) -C docs html - -test: - @nosetests -s - -coverage: - @rm -f .coverage - @nosetests --with-coverage --cover-package=livereload --cover-html diff --git a/docs/Makefile b/docs/Makefile deleted file mode 100644 index 8694e4f..0000000 --- a/docs/Makefile +++ /dev/null @@ -1,155 +0,0 @@ -# Makefile for Sphinx documentation -# - -# You can set these variables from the command line. -SPHINXOPTS = -SPHINXBUILD = sphinx-build -PAPER = -BUILDDIR = _build - -# Internal variables. -PAPEROPT_a4 = -D latex_paper_size=a4 -PAPEROPT_letter = -D latex_paper_size=letter -ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . - -.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext - -help: - @echo "Please use \`make ' where is one of" - @echo " html to make standalone HTML files" - @echo " dirhtml to make HTML files named index.html in directories" - @echo " singlehtml to make a single large HTML file" - @echo " pickle to make pickle files" - @echo " json to make JSON files" - @echo " htmlhelp to make HTML files and a HTML help project" - @echo " qthelp to make HTML files and a qthelp project" - @echo " devhelp to make HTML files and a Devhelp project" - @echo " epub to make an epub" - @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" - @echo " latexpdf to make LaTeX files and run them through pdflatex" - @echo " text to make text files" - @echo " man to make manual pages" - @echo " texinfo to make Texinfo files" - @echo " info to make Texinfo files and run them through makeinfo" - @echo " gettext to make PO message catalogs" - @echo " changes to make an overview of all changed/added/deprecated items" - @echo " linkcheck to check all external links for integrity" - @echo " doctest to run all doctests embedded in the documentation (if enabled)" - -clean: - -rm -rf $(BUILDDIR)/* - -html: _themes/.git - $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html - @echo - @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." - -dirhtml: - $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml - @echo - @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." - -singlehtml: - $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml - @echo - @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." - -pickle: - $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle - @echo - @echo "Build finished; now you can process the pickle files." - -json: - $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json - @echo - @echo "Build finished; now you can process the JSON files." - -htmlhelp: - $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp - @echo - @echo "Build finished; now you can run HTML Help Workshop with the" \ - ".hhp project file in $(BUILDDIR)/htmlhelp." - -qthelp: - $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp - @echo - @echo "Build finished; now you can run "qcollectiongenerator" with the" \ - ".qhcp project file in $(BUILDDIR)/qthelp, like this:" - @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/PythonLiveReload.qhcp" - @echo "To view the help file:" - @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/PythonLiveReload.qhc" - -devhelp: - $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp - @echo - @echo "Build finished." - @echo "To view the help file:" - @echo "# mkdir -p $$HOME/.local/share/devhelp/PythonLiveReload" - @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/PythonLiveReload" - @echo "# devhelp" - -epub: - $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub - @echo - @echo "Build finished. The epub file is in $(BUILDDIR)/epub." - -latex: - $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex - @echo - @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." - @echo "Run \`make' in that directory to run these through (pdf)latex" \ - "(use \`make latexpdf' here to do that automatically)." - -latexpdf: - $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex - @echo "Running LaTeX files through pdflatex..." - $(MAKE) -C $(BUILDDIR)/latex all-pdf - @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." - -text: - $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text - @echo - @echo "Build finished. The text files are in $(BUILDDIR)/text." - -man: - $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man - @echo - @echo "Build finished. The manual pages are in $(BUILDDIR)/man." - -texinfo: - $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo - @echo - @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo." - @echo "Run \`make' in that directory to run these through makeinfo" \ - "(use \`make info' here to do that automatically)." - -info: - $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo - @echo "Running Texinfo files through makeinfo..." - make -C $(BUILDDIR)/texinfo info - @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo." - -gettext: - $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale - @echo - @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale." - -changes: - $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes - @echo - @echo "The overview file is in $(BUILDDIR)/changes." - -linkcheck: - $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck - @echo - @echo "Link check complete; look for any errors in the above output " \ - "or in $(BUILDDIR)/linkcheck/output.txt." - -doctest: - $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest - @echo "Testing of doctests in the sources finished, look at the " \ - "results in $(BUILDDIR)/doctest/output.txt." - - -_themes/.git: - git submodule update --init diff --git a/docs/_templates/sidebarintro.html b/docs/_templates/sidebarintro.html deleted file mode 100644 index 0f3b2d2..0000000 --- a/docs/_templates/sidebarintro.html +++ /dev/null @@ -1,3 +0,0 @@ -

About LiveReload

-

LiveReload is an awsome tool for web developers, it helps web developers auto -refreshing their browsers when something changed.

diff --git a/docs/_themes b/docs/_themes deleted file mode 160000 index 6298bdf..0000000 --- a/docs/_themes +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 6298bdfc8d204ca42288fe8e567541c22a6e905e diff --git a/docs/conf.py b/docs/conf.py index 8f383ba..b062be2 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -1,250 +1,54 @@ +# Configuration file for the Sphinx documentation builder. # -# Python LiveReload documentation build configuration file, created by -# sphinx-quickstart on Sat May 5 18:36:44 2012. -# -# This file is execfile()d with the current directory set to its containing dir. -# -# Note that not all possible configuration values are present in this -# autogenerated file. -# -# All configuration values have a default; values that are commented out -# serve to show the default. - -import sys, os -sys.path.append(os.path.abspath('_themes')) -sys.path.append(os.path.abspath('.')) - -# If extensions (or modules to document with autodoc) are in another directory, -# add these directories to sys.path here. If the directory is relative to the -# documentation root, use os.path.abspath to make it absolute, like shown here. -#sys.path.insert(0, os.path.abspath('.')) - -# -- General configuration ----------------------------------------------------- - -# If your documentation needs a minimal Sphinx version, state it here. -#needs_sphinx = '1.0' - -# 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.viewcode'] - -# Add any paths that contain templates here, relative to this directory. -templates_path = ['_templates'] - -# The suffix of source filenames. -source_suffix = '.rst' +# Full list of options can be found in the Sphinx documentation: +# https://www.sphinx-doc.org/en/master/usage/configuration.html -# The encoding of source files. -#source_encoding = 'utf-8-sig' +import os +import sys -# The master toctree document. -master_doc = 'index' +# add the demo python code to the path, so that it can be used to demonstrate +# source links +sys.path.append(os.path.abspath("./kitchen-sink/demo_py")) -# General information about the project. -project = 'Python LiveReload' -copyright = '2012, Hsiaoming Yang' - -# The version info for the project you're documenting, acts as replacement for -# |version| and |release|, also used in various other places throughout the -# built documents. # -# The short X.Y version. -version = '0.3' -# The full version, including alpha/beta/rc tags. -release = '0.3' - -# The language for content autogenerated by Sphinx. Refer to documentation -# for a list of supported languages. -#language = None - -# There are two options for replacing |today|: either, you set today to some -# non-false value, then it is used: -#today = '' -# Else, today_fmt is used as the format for a strftime call. -#today_fmt = '%B %d, %Y' - -# List of patterns, relative to source directory, that match files and -# directories to ignore when looking for source files. -exclude_patterns = ['_build'] - -# The reST default role (used for this markup: `text`) to use for all documents. -#default_role = None - -# If true, '()' will be appended to :func: etc. cross-reference text. -#add_function_parentheses = True - -# If true, the current module name will be prepended to all description -# unit titles (such as .. function::). -#add_module_names = True - -# If true, sectionauthor and moduleauthor directives will be shown in the -# output. They are ignored by default. -#show_authors = False - -# The name of the Pygments (syntax highlighting) style to use. -pygments_style = 'sphinx' - -# A list of ignored prefixes for module index sorting. -#modindex_common_prefix = [] - - -# -- Options for HTML output --------------------------------------------------- - -# The theme to use for HTML and HTML Help pages. See the documentation for -# a list of builtin themes. -html_theme = 'flask_small' - -# 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 -# documentation. -html_theme_options = { - 'index_logo': None, - 'github_fork': 'lepture/python-livereload', -} - -# Add any paths that contain custom themes here, relative to this directory. -html_theme_path = ['_themes'] - -# The name for this set of Sphinx documents. If None, it defaults to -# " v documentation". -#html_title = None - -# A shorter title for the navigation bar. Default is the same as html_title. -#html_short_title = None - -# The name of an image file (relative to this directory) to place at the top -# of the sidebar. -#html_logo = None - -# The name of an image file (within the static path) to use as favicon of the -# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 -# pixels large. -#html_favicon = None +# -- Project information ----------------------------------------------------- +# -# 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'] +project = "livereload" +copyright = "2021, Pradyun Gedam" +author = "Hsiaoming Yang" -# If not '', a 'Last updated on:' timestamp is inserted at every page bottom, -# using the given strftime format. -#html_last_updated_fmt = '%b %d, %Y' +# +# -- General configuration --------------------------------------------------- +# -# If true, SmartyPants will be used to convert quotes and dashes to -# typographically correct entities. -#html_use_smartypants = True +extensions = [ + # Sphinx's own extensions + "sphinx.ext.autodoc", + "sphinx.ext.extlinks", + "sphinx.ext.intersphinx", + "sphinx.ext.viewcode", +] +templates_path = ["_templates"] -# Custom sidebar templates, maps document names to template names. -html_sidebars = { - 'index': ['sidebarintro.html', 'sourcelink.html', 'searchbox.html'], - '**': ['sidebarintro.html', 'localtoc.html', 'relations.html', - 'sourcelink.html', 'searchbox.html'] +# +# -- Options for extlinks ---------------------------------------------------- +# +extlinks = { + "pypi": ("https://pypi.org/project/%s/", ""), } -# Additional templates that should be rendered to pages, maps page names to -# template names. -#html_additional_pages = {} - -# If false, no module index is generated. -#html_domain_indices = True - -# If false, no index is generated. -#html_use_index = True - -# If true, the index is split into individual pages for each letter. -#html_split_index = False - -# If true, links to the reST sources are added to the pages. -#html_show_sourcelink = True - -# If true, "Created using Sphinx" is shown in the HTML footer. Default is True. -#html_show_sphinx = True - -# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. -#html_show_copyright = True - -# If true, an OpenSearch description file will be output, and all pages will -# contain a tag referring to it. The value of this option must be the -# base URL from which the finished HTML is served. -#html_use_opensearch = '' - -# This is the file name suffix for HTML files (e.g. ".xhtml"). -#html_file_suffix = None - -# Output file base name for HTML help builder. -htmlhelp_basename = 'PythonLiveReloaddoc' - - -# -- Options for LaTeX output -------------------------------------------------- - -latex_elements = { -# The paper size ('letterpaper' or 'a4paper'). -#'papersize': 'letterpaper', - -# The font size ('10pt', '11pt' or '12pt'). -#'pointsize': '10pt', - -# Additional stuff for the LaTeX preamble. -#'preamble': '', +# +# -- Options for intersphinx ------------------------------------------------- +# +intersphinx_mapping = { + "python": ("https://docs.python.org/3", None), + "sphinx": ("https://www.sphinx-doc.org/en/master", None), } -# Grouping the document tree into LaTeX files. List of tuples -# (source start file, target name, title, author, documentclass [howto/manual]). -latex_documents = [ - ('index', 'PythonLiveReload.tex', 'Python LiveReload Documentation', - 'Hsiaoming Yang', 'manual'), -] - -# The name of an image file (relative to this directory) to place at the top of -# the title page. -#latex_logo = None - -# For "manual" documents, if this is true, then toplevel headings are parts, -# not chapters. -#latex_use_parts = False - -# If true, show page references after internal links. -#latex_show_pagerefs = False - -# If true, show URL addresses after external links. -#latex_show_urls = False - -# Documents to append as an appendix to all manuals. -#latex_appendices = [] - -# If false, no module index is generated. -#latex_domain_indices = True - - -# -- Options for manual page output -------------------------------------------- - -# One entry per manual page. List of tuples -# (source start file, name, description, authors, manual section). -man_pages = [ - ('index', 'livereload', 'Python LiveReload Documentation', - ['Hsiaoming Yang'], 1) -] - -# If true, show URL addresses after external links. -#man_show_urls = False - - -# -- Options for Texinfo output ------------------------------------------------ - -# Grouping the document tree into Texinfo files. List of tuples -# (source start file, target name, title, author, -# dir menu entry, description, category) -texinfo_documents = [ - ('index', 'PythonLiveReload', 'Python LiveReload Documentation', - 'Hsiaoming Yang', 'PythonLiveReload', 'One line description of project.', - 'Miscellaneous'), -] - -# Documents to append as an appendix to all manuals. -#texinfo_appendices = [] - -# If false, no module index is generated. -#texinfo_domain_indices = True - -# How to display URL addresses: 'footnote', 'no', or 'inline'. -#texinfo_show_urls = 'footnote' +# +# -- Options for HTML output ------------------------------------------------- +# +html_theme = "furo" +html_title = "Python LiveReload" +language = "en" diff --git a/docs/requirements.txt b/docs/requirements.txt new file mode 100644 index 0000000..a95ae18 --- /dev/null +++ b/docs/requirements.txt @@ -0,0 +1 @@ +furo diff --git a/livereload/vendors/livereload.js b/livereload/vendors/livereload.js deleted file mode 100644 index 12a7c47..0000000 --- a/livereload/vendors/livereload.js +++ /dev/null @@ -1,1155 +0,0 @@ -(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o tag"); - return; - } - this.reloader = new Reloader(this.window, this.console, Timer); - this.connector = new Connector(this.options, this.WebSocket, Timer, { - connecting: (function(_this) { - return function() {}; - })(this), - socketConnected: (function(_this) { - return function() {}; - })(this), - connected: (function(_this) { - return function(protocol) { - var _base; - if (typeof (_base = _this.listeners).connect === "function") { - _base.connect(); - } - _this.log("LiveReload is connected to " + _this.options.host + ":" + _this.options.port + " (protocol v" + protocol + ")."); - return _this.analyze(); - }; - })(this), - error: (function(_this) { - return function(e) { - if (e instanceof ProtocolError) { - if (typeof console !== "undefined" && console !== null) { - return console.log("" + e.message + "."); - } - } else { - if (typeof console !== "undefined" && console !== null) { - return console.log("LiveReload internal error: " + e.message); - } - } - }; - })(this), - disconnected: (function(_this) { - return function(reason, nextDelay) { - var _base; - if (typeof (_base = _this.listeners).disconnect === "function") { - _base.disconnect(); - } - switch (reason) { - case 'cannot-connect': - return _this.log("LiveReload cannot connect to " + _this.options.host + ":" + _this.options.port + ", will retry in " + nextDelay + " sec."); - case 'broken': - return _this.log("LiveReload disconnected from " + _this.options.host + ":" + _this.options.port + ", reconnecting in " + nextDelay + " sec."); - case 'handshake-timeout': - return _this.log("LiveReload cannot connect to " + _this.options.host + ":" + _this.options.port + " (handshake timeout), will retry in " + nextDelay + " sec."); - case 'handshake-failed': - return _this.log("LiveReload cannot connect to " + _this.options.host + ":" + _this.options.port + " (handshake failed), will retry in " + nextDelay + " sec."); - case 'manual': - break; - case 'error': - break; - default: - return _this.log("LiveReload disconnected from " + _this.options.host + ":" + _this.options.port + " (" + reason + "), reconnecting in " + nextDelay + " sec."); - } - }; - })(this), - message: (function(_this) { - return function(message) { - switch (message.command) { - case 'reload': - return _this.performReload(message); - case 'alert': - return _this.performAlert(message); - } - }; - })(this) - }); - } - - LiveReload.prototype.on = function(eventName, handler) { - return this.listeners[eventName] = handler; - }; - - LiveReload.prototype.log = function(message) { - return this.console.log("" + message); - }; - - LiveReload.prototype.performReload = function(message) { - var _ref, _ref1; - this.log("LiveReload received reload request: " + (JSON.stringify(message, null, 2))); - return this.reloader.reload(message.path, { - liveCSS: (_ref = message.liveCSS) != null ? _ref : true, - liveImg: (_ref1 = message.liveImg) != null ? _ref1 : true, - originalPath: message.originalPath || '', - overrideURL: message.overrideURL || '', - serverURL: "http://" + this.options.host + ":" + this.options.port - }); - }; - - LiveReload.prototype.performAlert = function(message) { - return alert(message.message); - }; - - LiveReload.prototype.shutDown = function() { - var _base; - this.connector.disconnect(); - this.log("LiveReload disconnected."); - return typeof (_base = this.listeners).shutdown === "function" ? _base.shutdown() : void 0; - }; - - LiveReload.prototype.hasPlugin = function(identifier) { - return !!this.pluginIdentifiers[identifier]; - }; - - LiveReload.prototype.addPlugin = function(pluginClass) { - var plugin; - if (this.hasPlugin(pluginClass.identifier)) { - return; - } - this.pluginIdentifiers[pluginClass.identifier] = true; - plugin = new pluginClass(this.window, { - _livereload: this, - _reloader: this.reloader, - _connector: this.connector, - console: this.console, - Timer: Timer, - generateCacheBustUrl: (function(_this) { - return function(url) { - return _this.reloader.generateCacheBustUrl(url); - }; - })(this) - }); - this.plugins.push(plugin); - this.reloader.addPlugin(plugin); - }; - - LiveReload.prototype.analyze = function() { - var plugin, pluginData, pluginsData, _i, _len, _ref; - if (!(this.connector.protocol >= 7)) { - return; - } - pluginsData = {}; - _ref = this.plugins; - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - plugin = _ref[_i]; - pluginsData[plugin.constructor.identifier] = pluginData = (typeof plugin.analyze === "function" ? plugin.analyze() : void 0) || {}; - pluginData.version = plugin.constructor.version; - } - this.connector.sendCommand({ - command: 'info', - plugins: pluginsData, - url: this.window.location.href - }); - }; - - return LiveReload; - - })(); - -}).call(this); - -},{"./connector":1,"./options":5,"./reloader":7,"./timer":9}],5:[function(require,module,exports){ -(function() { - var Options; - - exports.Options = Options = (function() { - function Options() { - this.host = null; - this.port = 35729; - this.snipver = null; - this.ext = null; - this.extver = null; - this.mindelay = 1000; - this.maxdelay = 60000; - this.handshake_timeout = 5000; - } - - Options.prototype.set = function(name, value) { - if (typeof value === 'undefined') { - return; - } - if (!isNaN(+value)) { - value = +value; - } - return this[name] = value; - }; - - return Options; - - })(); - - Options.extract = function(document) { - var element, keyAndValue, m, mm, options, pair, src, _i, _j, _len, _len1, _ref, _ref1; - _ref = document.getElementsByTagName('script'); - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - element = _ref[_i]; - if ((src = element.src) && (m = src.match(/^[^:]+:\/\/(.*)\/z?livereload\.js(?:\?(.*))?$/))) { - options = new Options(); - if (mm = m[1].match(/^([^\/:]+)(?::(\d+))?$/)) { - options.host = mm[1]; - if (mm[2]) { - options.port = parseInt(mm[2], 10); - } - } - if (m[2]) { - _ref1 = m[2].split('&'); - for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) { - pair = _ref1[_j]; - if ((keyAndValue = pair.split('=')).length > 1) { - options.set(keyAndValue[0].replace(/-/g, '_'), keyAndValue.slice(1).join('=')); - } - } - } - return options; - } - } - return null; - }; - -}).call(this); - -},{}],6:[function(require,module,exports){ -(function() { - var PROTOCOL_6, PROTOCOL_7, Parser, ProtocolError, - __indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }; - - exports.PROTOCOL_6 = PROTOCOL_6 = 'http://livereload.com/protocols/official-6'; - - exports.PROTOCOL_7 = PROTOCOL_7 = 'http://livereload.com/protocols/official-7'; - - exports.ProtocolError = ProtocolError = (function() { - function ProtocolError(reason, data) { - this.message = "LiveReload protocol error (" + reason + ") after receiving data: \"" + data + "\"."; - } - - return ProtocolError; - - })(); - - exports.Parser = Parser = (function() { - function Parser(handlers) { - this.handlers = handlers; - this.reset(); - } - - Parser.prototype.reset = function() { - return this.protocol = null; - }; - - Parser.prototype.process = function(data) { - var command, e, message, options, _ref; - try { - if (this.protocol == null) { - if (data.match(/^!!ver:([\d.]+)$/)) { - this.protocol = 6; - } else if (message = this._parseMessage(data, ['hello'])) { - if (!message.protocols.length) { - throw new ProtocolError("no protocols specified in handshake message"); - } else if (__indexOf.call(message.protocols, PROTOCOL_7) >= 0) { - this.protocol = 7; - } else if (__indexOf.call(message.protocols, PROTOCOL_6) >= 0) { - this.protocol = 6; - } else { - throw new ProtocolError("no supported protocols found"); - } - } - return this.handlers.connected(this.protocol); - } else if (this.protocol === 6) { - message = JSON.parse(data); - if (!message.length) { - throw new ProtocolError("protocol 6 messages must be arrays"); - } - command = message[0], options = message[1]; - if (command !== 'refresh') { - throw new ProtocolError("unknown protocol 6 command"); - } - return this.handlers.message({ - command: 'reload', - path: options.path, - liveCSS: (_ref = options.apply_css_live) != null ? _ref : true - }); - } else { - message = this._parseMessage(data, ['reload', 'alert']); - return this.handlers.message(message); - } - } catch (_error) { - e = _error; - if (e instanceof ProtocolError) { - return this.handlers.error(e); - } else { - throw e; - } - } - }; - - Parser.prototype._parseMessage = function(data, validCommands) { - var e, message, _ref; - try { - message = JSON.parse(data); - } catch (_error) { - e = _error; - throw new ProtocolError('unparsable JSON', data); - } - if (!message.command) { - throw new ProtocolError('missing "command" key', data); - } - if (_ref = message.command, __indexOf.call(validCommands, _ref) < 0) { - throw new ProtocolError("invalid command '" + message.command + "', only valid commands are: " + (validCommands.join(', ')) + ")", data); - } - return message; - }; - - return Parser; - - })(); - -}).call(this); - -},{}],7:[function(require,module,exports){ -(function() { - var IMAGE_STYLES, Reloader, numberOfMatchingSegments, pathFromUrl, pathsMatch, pickBestMatch, splitUrl; - - splitUrl = function(url) { - var hash, index, params; - if ((index = url.indexOf('#')) >= 0) { - hash = url.slice(index); - url = url.slice(0, index); - } else { - hash = ''; - } - if ((index = url.indexOf('?')) >= 0) { - params = url.slice(index); - url = url.slice(0, index); - } else { - params = ''; - } - return { - url: url, - params: params, - hash: hash - }; - }; - - pathFromUrl = function(url) { - var path; - url = splitUrl(url).url; - if (url.indexOf('file://') === 0) { - path = url.replace(/^file:\/\/(localhost)?/, ''); - } else { - path = url.replace(/^([^:]+:)?\/\/([^:\/]+)(:\d*)?\//, '/'); - } - return decodeURIComponent(path); - }; - - pickBestMatch = function(path, objects, pathFunc) { - var bestMatch, object, score, _i, _len; - bestMatch = { - score: 0 - }; - for (_i = 0, _len = objects.length; _i < _len; _i++) { - object = objects[_i]; - score = numberOfMatchingSegments(path, pathFunc(object)); - if (score > bestMatch.score) { - bestMatch = { - object: object, - score: score - }; - } - } - if (bestMatch.score > 0) { - return bestMatch; - } else { - return null; - } - }; - - numberOfMatchingSegments = function(path1, path2) { - var comps1, comps2, eqCount, len; - path1 = path1.replace(/^\/+/, '').toLowerCase(); - path2 = path2.replace(/^\/+/, '').toLowerCase(); - if (path1 === path2) { - return 10000; - } - comps1 = path1.split('/').reverse(); - comps2 = path2.split('/').reverse(); - len = Math.min(comps1.length, comps2.length); - eqCount = 0; - while (eqCount < len && comps1[eqCount] === comps2[eqCount]) { - ++eqCount; - } - return eqCount; - }; - - pathsMatch = function(path1, path2) { - return numberOfMatchingSegments(path1, path2) > 0; - }; - - IMAGE_STYLES = [ - { - selector: 'background', - styleNames: ['backgroundImage'] - }, { - selector: 'border', - styleNames: ['borderImage', 'webkitBorderImage', 'MozBorderImage'] - } - ]; - - exports.Reloader = Reloader = (function() { - function Reloader(window, console, Timer) { - this.window = window; - this.console = console; - this.Timer = Timer; - this.document = this.window.document; - this.importCacheWaitPeriod = 200; - this.plugins = []; - } - - Reloader.prototype.addPlugin = function(plugin) { - return this.plugins.push(plugin); - }; - - Reloader.prototype.analyze = function(callback) { - return results; - }; - - Reloader.prototype.reload = function(path, options) { - var plugin, _base, _i, _len, _ref; - this.options = options; - if ((_base = this.options).stylesheetReloadTimeout == null) { - _base.stylesheetReloadTimeout = 15000; - } - _ref = this.plugins; - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - plugin = _ref[_i]; - if (plugin.reload && plugin.reload(path, options)) { - return; - } - } - if (options.liveCSS) { - if (path.match(/\.css$/i)) { - if (this.reloadStylesheet(path)) { - return; - } - } - } - if (options.liveImg) { - if (path.match(/\.(jpe?g|png|gif)$/i)) { - this.reloadImages(path); - return; - } - } - return this.reloadPage(); - }; - - Reloader.prototype.reloadPage = function() { - return this.window.document.location.reload(); - }; - - Reloader.prototype.reloadImages = function(path) { - var expando, img, selector, styleNames, styleSheet, _i, _j, _k, _l, _len, _len1, _len2, _len3, _ref, _ref1, _ref2, _ref3, _results; - expando = this.generateUniqueString(); - _ref = this.document.images; - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - img = _ref[_i]; - if (pathsMatch(path, pathFromUrl(img.src))) { - img.src = this.generateCacheBustUrl(img.src, expando); - } - } - if (this.document.querySelectorAll) { - for (_j = 0, _len1 = IMAGE_STYLES.length; _j < _len1; _j++) { - _ref1 = IMAGE_STYLES[_j], selector = _ref1.selector, styleNames = _ref1.styleNames; - _ref2 = this.document.querySelectorAll("[style*=" + selector + "]"); - for (_k = 0, _len2 = _ref2.length; _k < _len2; _k++) { - img = _ref2[_k]; - this.reloadStyleImages(img.style, styleNames, path, expando); - } - } - } - if (this.document.styleSheets) { - _ref3 = this.document.styleSheets; - _results = []; - for (_l = 0, _len3 = _ref3.length; _l < _len3; _l++) { - styleSheet = _ref3[_l]; - _results.push(this.reloadStylesheetImages(styleSheet, path, expando)); - } - return _results; - } - }; - - Reloader.prototype.reloadStylesheetImages = function(styleSheet, path, expando) { - var e, rule, rules, styleNames, _i, _j, _len, _len1; - try { - rules = styleSheet != null ? styleSheet.cssRules : void 0; - } catch (_error) { - e = _error; - } - if (!rules) { - return; - } - for (_i = 0, _len = rules.length; _i < _len; _i++) { - rule = rules[_i]; - switch (rule.type) { - case CSSRule.IMPORT_RULE: - this.reloadStylesheetImages(rule.styleSheet, path, expando); - break; - case CSSRule.STYLE_RULE: - for (_j = 0, _len1 = IMAGE_STYLES.length; _j < _len1; _j++) { - styleNames = IMAGE_STYLES[_j].styleNames; - this.reloadStyleImages(rule.style, styleNames, path, expando); - } - break; - case CSSRule.MEDIA_RULE: - this.reloadStylesheetImages(rule, path, expando); - } - } - }; - - Reloader.prototype.reloadStyleImages = function(style, styleNames, path, expando) { - var newValue, styleName, value, _i, _len; - for (_i = 0, _len = styleNames.length; _i < _len; _i++) { - styleName = styleNames[_i]; - value = style[styleName]; - if (typeof value === 'string') { - newValue = value.replace(/\burl\s*\(([^)]*)\)/, (function(_this) { - return function(match, src) { - if (pathsMatch(path, pathFromUrl(src))) { - return "url(" + (_this.generateCacheBustUrl(src, expando)) + ")"; - } else { - return match; - } - }; - })(this)); - if (newValue !== value) { - style[styleName] = newValue; - } - } - } - }; - - Reloader.prototype.reloadStylesheet = function(path) { - var imported, link, links, match, style, _i, _j, _k, _l, _len, _len1, _len2, _len3, _ref, _ref1; - links = (function() { - var _i, _len, _ref, _results; - _ref = this.document.getElementsByTagName('link'); - _results = []; - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - link = _ref[_i]; - if (link.rel.match(/^stylesheet$/i) && !link.__LiveReload_pendingRemoval) { - _results.push(link); - } - } - return _results; - }).call(this); - imported = []; - _ref = this.document.getElementsByTagName('style'); - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - style = _ref[_i]; - if (style.sheet) { - this.collectImportedStylesheets(style, style.sheet, imported); - } - } - for (_j = 0, _len1 = links.length; _j < _len1; _j++) { - link = links[_j]; - this.collectImportedStylesheets(link, link.sheet, imported); - } - if (this.window.StyleFix && this.document.querySelectorAll) { - _ref1 = this.document.querySelectorAll('style[data-href]'); - for (_k = 0, _len2 = _ref1.length; _k < _len2; _k++) { - style = _ref1[_k]; - links.push(style); - } - } - this.console.log("LiveReload found " + links.length + " LINKed stylesheets, " + imported.length + " @imported stylesheets"); - match = pickBestMatch(path, links.concat(imported), (function(_this) { - return function(l) { - return pathFromUrl(_this.linkHref(l)); - }; - })(this)); - if (match) { - if (match.object.rule) { - this.console.log("LiveReload is reloading imported stylesheet: " + match.object.href); - this.reattachImportedRule(match.object); - } else { - this.console.log("LiveReload is reloading stylesheet: " + (this.linkHref(match.object))); - this.reattachStylesheetLink(match.object); - } - } else { - this.console.log("LiveReload will reload all stylesheets because path '" + path + "' did not match any specific one"); - for (_l = 0, _len3 = links.length; _l < _len3; _l++) { - link = links[_l]; - this.reattachStylesheetLink(link); - } - } - return true; - }; - - Reloader.prototype.collectImportedStylesheets = function(link, styleSheet, result) { - var e, index, rule, rules, _i, _len; - try { - rules = styleSheet != null ? styleSheet.cssRules : void 0; - } catch (_error) { - e = _error; - } - if (rules && rules.length) { - for (index = _i = 0, _len = rules.length; _i < _len; index = ++_i) { - rule = rules[index]; - switch (rule.type) { - case CSSRule.CHARSET_RULE: - continue; - case CSSRule.IMPORT_RULE: - result.push({ - link: link, - rule: rule, - index: index, - href: rule.href - }); - this.collectImportedStylesheets(link, rule.styleSheet, result); - break; - default: - break; - } - } - } - }; - - Reloader.prototype.waitUntilCssLoads = function(clone, func) { - var callbackExecuted, executeCallback, poll; - callbackExecuted = false; - executeCallback = (function(_this) { - return function() { - if (callbackExecuted) { - return; - } - callbackExecuted = true; - return func(); - }; - })(this); - clone.onload = (function(_this) { - return function() { - _this.console.log("LiveReload: the new stylesheet has finished loading"); - _this.knownToSupportCssOnLoad = true; - return executeCallback(); - }; - })(this); - if (!this.knownToSupportCssOnLoad) { - (poll = (function(_this) { - return function() { - if (clone.sheet) { - _this.console.log("LiveReload is polling until the new CSS finishes loading..."); - return executeCallback(); - } else { - return _this.Timer.start(50, poll); - } - }; - })(this))(); - } - return this.Timer.start(this.options.stylesheetReloadTimeout, executeCallback); - }; - - Reloader.prototype.linkHref = function(link) { - return link.href || link.getAttribute('data-href'); - }; - - Reloader.prototype.reattachStylesheetLink = function(link) { - var clone, parent; - if (link.__LiveReload_pendingRemoval) { - return; - } - link.__LiveReload_pendingRemoval = true; - if (link.tagName === 'STYLE') { - clone = this.document.createElement('link'); - clone.rel = 'stylesheet'; - clone.media = link.media; - clone.disabled = link.disabled; - } else { - clone = link.cloneNode(false); - } - clone.href = this.generateCacheBustUrl(this.linkHref(link)); - parent = link.parentNode; - if (parent.lastChild === link) { - parent.appendChild(clone); - } else { - parent.insertBefore(clone, link.nextSibling); - } - return this.waitUntilCssLoads(clone, (function(_this) { - return function() { - var additionalWaitingTime; - if (/AppleWebKit/.test(navigator.userAgent)) { - additionalWaitingTime = 5; - } else { - additionalWaitingTime = 200; - } - return _this.Timer.start(additionalWaitingTime, function() { - var _ref; - if (!link.parentNode) { - return; - } - link.parentNode.removeChild(link); - clone.onreadystatechange = null; - return (_ref = _this.window.StyleFix) != null ? _ref.link(clone) : void 0; - }); - }; - })(this)); - }; - - Reloader.prototype.reattachImportedRule = function(_arg) { - var href, index, link, media, newRule, parent, rule, tempLink; - rule = _arg.rule, index = _arg.index, link = _arg.link; - parent = rule.parentStyleSheet; - href = this.generateCacheBustUrl(rule.href); - media = rule.media.length ? [].join.call(rule.media, ', ') : ''; - newRule = "@import url(\"" + href + "\") " + media + ";"; - rule.__LiveReload_newHref = href; - tempLink = this.document.createElement("link"); - tempLink.rel = 'stylesheet'; - tempLink.href = href; - tempLink.__LiveReload_pendingRemoval = true; - if (link.parentNode) { - link.parentNode.insertBefore(tempLink, link); - } - return this.Timer.start(this.importCacheWaitPeriod, (function(_this) { - return function() { - if (tempLink.parentNode) { - tempLink.parentNode.removeChild(tempLink); - } - if (rule.__LiveReload_newHref !== href) { - return; - } - parent.insertRule(newRule, index); - parent.deleteRule(index + 1); - rule = parent.cssRules[index]; - rule.__LiveReload_newHref = href; - return _this.Timer.start(_this.importCacheWaitPeriod, function() { - if (rule.__LiveReload_newHref !== href) { - return; - } - parent.insertRule(newRule, index); - return parent.deleteRule(index + 1); - }); - }; - })(this)); - }; - - Reloader.prototype.generateUniqueString = function() { - return 'livereload=' + Date.now(); - }; - - Reloader.prototype.generateCacheBustUrl = function(url, expando) { - var hash, oldParams, originalUrl, params, _ref; - if (expando == null) { - expando = this.generateUniqueString(); - } - _ref = splitUrl(url), url = _ref.url, hash = _ref.hash, oldParams = _ref.params; - if (this.options.overrideURL) { - if (url.indexOf(this.options.serverURL) < 0) { - originalUrl = url; - url = this.options.serverURL + this.options.overrideURL + "?url=" + encodeURIComponent(url); - this.console.log("LiveReload is overriding source URL " + originalUrl + " with " + url); - } - } - params = oldParams.replace(/(\?|&)livereload=(\d+)/, function(match, sep) { - return "" + sep + expando; - }); - if (params === oldParams) { - if (oldParams.length === 0) { - params = "?" + expando; - } else { - params = "" + oldParams + "&" + expando; - } - } - return url + params + hash; - }; - - return Reloader; - - })(); - -}).call(this); - -},{}],8:[function(require,module,exports){ -(function() { - var CustomEvents, LiveReload, k; - - CustomEvents = require('./customevents'); - - LiveReload = window.LiveReload = new (require('./livereload').LiveReload)(window); - - for (k in window) { - if (k.match(/^LiveReloadPlugin/)) { - LiveReload.addPlugin(window[k]); - } - } - - LiveReload.addPlugin(require('./less')); - - LiveReload.on('shutdown', function() { - return delete window.LiveReload; - }); - - LiveReload.on('connect', function() { - return CustomEvents.fire(document, 'LiveReloadConnect'); - }); - - LiveReload.on('disconnect', function() { - return CustomEvents.fire(document, 'LiveReloadDisconnect'); - }); - - CustomEvents.bind(document, 'LiveReloadShutDown', function() { - return LiveReload.shutDown(); - }); - -}).call(this); - -},{"./customevents":2,"./less":3,"./livereload":4}],9:[function(require,module,exports){ -(function() { - var Timer; - - exports.Timer = Timer = (function() { - function Timer(func) { - this.func = func; - this.running = false; - this.id = null; - this._handler = (function(_this) { - return function() { - _this.running = false; - _this.id = null; - return _this.func(); - }; - })(this); - } - - Timer.prototype.start = function(timeout) { - if (this.running) { - clearTimeout(this.id); - } - this.id = setTimeout(this._handler, timeout); - return this.running = true; - }; - - Timer.prototype.stop = function() { - if (this.running) { - clearTimeout(this.id); - this.running = false; - return this.id = null; - } - }; - - return Timer; - - })(); - - Timer.start = function(timeout, func) { - return setTimeout(func, timeout); - }; - -}).call(this); - -},{}]},{},[8]); diff --git a/noxfile.py b/noxfile.py new file mode 100644 index 0000000..c8e3837 --- /dev/null +++ b/noxfile.py @@ -0,0 +1,65 @@ +"""Development automation +""" +import os +import tempfile + +import nox + +PACKAGE_NAME = "livereload" +nox.options.sessions = ["test"] + + +# +# Helpers +# +def _install_this_project_with_flit(session, *, extras=None, editable=False): + session.install("flit") + args = [] + if extras: + args.append("--extras") + args.append(",".join(extras)) + if editable: + args.append("--pth-file" if os.name == "nt" else "--symlink") + + session.run("flit", "install", "--deps=production", *args, silent=True) + + +# +# Development Sessions +# +@nox.session(name="docs-live", reuse_venv=True) +def docs_live(session): + _install_this_project_with_flit(session, editable=False) + session.install("-r", "docs/requirements.txt") + session.install("sphinx-autobuild") + + with tempfile.TemporaryDirectory() as destination: + session.run( + "sphinx-autobuild", + # for sphinx-autobuild + "--port=0", + "--open-browser", + # for sphinx + "-b=dirhtml", + "-a", + "docs/", + destination, + ) + + +@nox.session(reuse_venv=True) +def docs(session): + _install_this_project_with_flit(session, editable=False) + session.install("-r", "docs/requirements.txt") + + # Generate documentation into `build/docs` + session.run("sphinx-build", "-b", "dirhtml", "-v", "docs/", "build/docs") + + +@nox.session(python=["3.6", "3.7", "3.8", "3.9", "3.10"]) +def test(session): + _install_this_project_with_flit(session) + session.install("-r", "tests/requirements.txt") + + args = session.posargs or ["--cov", PACKAGE_NAME] + session.run("pytest", *args) diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..e88e03e --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,48 @@ +[build-system] +requires = ["flit_core >=3.2,<4"] +build-backend = "flit_core.buildapi" + +[project] +dynamic = ["version", "description"] +name = "livereload" +readme = "README.rst" + +dependencies = ["tornado"] +license = { file = "LICENSE" } + +authors = [ + {name = "Hsiaoming Yang", email = "me@lepture.com"} +] +maintainers = [ + {name = "Pradyun Gedam", email = "mail@pradyunsg.me"} +] + +classifiers = [ + "Development Status :: 4 - Beta", + "Environment :: Console", + "Environment :: Web Environment :: Mozilla", + "Intended Audience :: Developers", + "License :: OSI Approved :: BSD License", + "Natural Language :: English", + "Operating System :: MacOS :: MacOS X", + "Operating System :: POSIX :: Linux", + "Programming Language :: Python", + "Programming Language :: Python :: 2", + "Programming Language :: Python :: 2.7", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.5", + "Programming Language :: Python :: 3.6", + "Programming Language :: Python :: 3.7", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: Implementation :: CPython", + "Programming Language :: Python :: Implementation :: PyPy", + "Topic :: Software Development :: Build Tools", + "Topic :: Software Development :: Compilers", + "Topic :: Software Development :: Debuggers", +] + +[project.urls] +Home = "https://github.com/lepture/python-livereload" + +[project.scripts] +livereload = "livereload.cli:main" diff --git a/server.py b/server.py deleted file mode 100644 index 0528a8a..0000000 --- a/server.py +++ /dev/null @@ -1,5 +0,0 @@ -from livereload import Server, shell - -server = Server() -server.watch('docs/*.rst', shell('make html')) -server.serve(root='docs/_build/html') diff --git a/setup.cfg b/setup.cfg deleted file mode 100644 index 0c9e0fc..0000000 --- a/setup.cfg +++ /dev/null @@ -1,2 +0,0 @@ -[metadata] -license_file = LICENSE diff --git a/setup.py b/setup.py deleted file mode 100644 index fc9a28d..0000000 --- a/setup.py +++ /dev/null @@ -1,62 +0,0 @@ -#!/usr/bin/env python - -import re -from setuptools import setup - - -def fread(filepath): - with open(filepath) as f: - return f.read() - - -def version(): - content = fread('livereload/__init__.py') - pattern = r"__version__ = '([0-9\.dev]*)'" - m = re.findall(pattern, content) - return m[0] - - -setup( - name='livereload', - version=version(), - author='Hsiaoming Yang', - author_email='me@lepture.com', - url='https://github.com/lepture/python-livereload', - packages=['livereload', 'livereload.management.commands'], - description='Python LiveReload is an awesome tool for web developers', - long_description_content_type='text/x-rst', - long_description=fread('README.rst'), - entry_points={ - 'console_scripts': [ - 'livereload = livereload.cli:main', - ] - }, - install_requires=[ - 'tornado', - ], - license='BSD', - include_package_data=True, - python_requires='>=3.6', - classifiers=[ - 'Development Status :: 4 - Beta', - 'Environment :: Console', - 'Environment :: Web Environment :: Mozilla', - 'Intended Audience :: Developers', - 'License :: OSI Approved :: BSD License', - 'Natural Language :: English', - 'Operating System :: MacOS :: MacOS X', - 'Operating System :: POSIX :: Linux', - 'Programming Language :: Python', - 'Programming Language :: Python :: 3', - 'Programming Language :: Python :: 3.6', - 'Programming Language :: Python :: 3.7', - 'Programming Language :: Python :: 3.8', - 'Programming Language :: Python :: 3.9', - 'Programming Language :: Python :: 3 :: Only', - 'Programming Language :: Python :: Implementation :: CPython', - 'Programming Language :: Python :: Implementation :: PyPy', - 'Topic :: Software Development :: Build Tools', - 'Topic :: Software Development :: Compilers', - 'Topic :: Software Development :: Debuggers', - ] -) diff --git a/livereload/__init__.py b/src/livereload/__init__.py similarity index 55% rename from livereload/__init__.py rename to src/livereload/__init__.py index 68be292..6e4c205 100644 --- a/livereload/__init__.py +++ b/src/livereload/__init__.py @@ -1,11 +1,4 @@ -""" - livereload - ~~~~~~~~~~ - - A python version of livereload. - - :copyright: (c) 2013 by Hsiaoming Yang - :license: BSD, see LICENSE for more details. +"""Reload webpages on changes, without hitting refresh in your browser. """ __version__ = '2.6.3' diff --git a/livereload/cli.py b/src/livereload/cli.py similarity index 100% rename from livereload/cli.py rename to src/livereload/cli.py diff --git a/livereload/handlers.py b/src/livereload/handlers.py similarity index 100% rename from livereload/handlers.py rename to src/livereload/handlers.py diff --git a/livereload/management/__init__.py b/src/livereload/management/__init__.py similarity index 100% rename from livereload/management/__init__.py rename to src/livereload/management/__init__.py diff --git a/livereload/management/commands/__init__.py b/src/livereload/management/commands/__init__.py similarity index 100% rename from livereload/management/commands/__init__.py rename to src/livereload/management/commands/__init__.py diff --git a/livereload/management/commands/livereload.py b/src/livereload/management/commands/livereload.py similarity index 100% rename from livereload/management/commands/livereload.py rename to src/livereload/management/commands/livereload.py diff --git a/livereload/server.py b/src/livereload/server.py similarity index 100% rename from livereload/server.py rename to src/livereload/server.py diff --git a/src/livereload/vendors/livereload.js b/src/livereload/vendors/livereload.js new file mode 100644 index 0000000..aa4bdb6 --- /dev/null +++ b/src/livereload/vendors/livereload.js @@ -0,0 +1 @@ +!function e(t,r,n){function o(s,c){if(!r[s]){if(!t[s]){var a="function"==typeof require&&require;if(!c&&a)return a(s,!0);if(i)return i(s,!0);var u=new Error("Cannot find module '"+s+"'");throw u.code="MODULE_NOT_FOUND",u}var l=r[s]={exports:{}};t[s][0].call(l.exports,(function(e){return o(t[s][1][e]||e)}),l,l.exports,e,t,r,n)}return r[s].exports}for(var i="function"==typeof require&&require,s=0;sl;)if((c=a[l++])!=c)return!0}else for(;u>l;l++)if((e||l in a)&&a[l]===r)return e||l||0;return!e&&-1}}},{"./_to-absolute-index":71,"./_to-iobject":73,"./_to-length":74}],6:[function(e,t,r){var n=e("./_ctx"),o=e("./_iobject"),i=e("./_to-object"),s=e("./_to-length"),c=e("./_array-species-create");t.exports=function(e,t){var r=1==e,a=2==e,u=3==e,l=4==e,f=6==e,d=5==e||f,p=t||c;return function(t,c,h){for(var _,y,g=i(t),m=o(g),v=n(c,h,3),b=s(m.length),j=0,w=r?p(t,b):a?p(t,0):void 0;b>j;j++)if((d||j in m)&&(y=v(_=m[j],j,g),e))if(r)w[j]=y;else if(y)switch(e){case 3:return!0;case 5:return _;case 6:return j;case 2:w.push(_)}else if(l)return!1;return f?-1:u||l?l:w}}},{"./_array-species-create":8,"./_ctx":13,"./_iobject":31,"./_to-length":74,"./_to-object":75}],7:[function(e,t,r){var n=e("./_is-object"),o=e("./_is-array"),i=e("./_wks")("species");t.exports=function(e){var t;return o(e)&&("function"!=typeof(t=e.constructor)||t!==Array&&!o(t.prototype)||(t=void 0),n(t)&&null===(t=t[i])&&(t=void 0)),void 0===t?Array:t}},{"./_is-array":33,"./_is-object":34,"./_wks":80}],8:[function(e,t,r){var n=e("./_array-species-constructor");t.exports=function(e,t){return new(n(e))(t)}},{"./_array-species-constructor":7}],9:[function(e,t,r){var n=e("./_cof"),o=e("./_wks")("toStringTag"),i="Arguments"==n(function(){return arguments}());t.exports=function(e){var t,r,s;return void 0===e?"Undefined":null===e?"Null":"string"==typeof(r=function(e,t){try{return e[t]}catch(e){}}(t=Object(e),o))?r:i?n(t):"Object"==(s=n(t))&&"function"==typeof t.callee?"Arguments":s}},{"./_cof":10,"./_wks":80}],10:[function(e,t,r){var n={}.toString;t.exports=function(e){return n.call(e).slice(8,-1)}},{}],11:[function(e,t,r){var n=t.exports={version:"2.6.12"};"number"==typeof __e&&(__e=n)},{}],12:[function(e,t,r){"use strict";var n=e("./_object-dp"),o=e("./_property-desc");t.exports=function(e,t,r){t in e?n.f(e,t,o(0,r)):e[t]=r}},{"./_object-dp":45,"./_property-desc":57}],13:[function(e,t,r){var n=e("./_a-function");t.exports=function(e,t,r){if(n(e),void 0===t)return e;switch(r){case 1:return function(r){return e.call(t,r)};case 2:return function(r,n){return e.call(t,r,n)};case 3:return function(r,n,o){return e.call(t,r,n,o)}}return function(){return e.apply(t,arguments)}}},{"./_a-function":1}],14:[function(e,t,r){t.exports=function(e){if(null==e)throw TypeError("Can't call method on "+e);return e}},{}],15:[function(e,t,r){t.exports=!e("./_fails")((function(){return 7!=Object.defineProperty({},"a",{get:function(){return 7}}).a}))},{"./_fails":21}],16:[function(e,t,r){var n=e("./_is-object"),o=e("./_global").document,i=n(o)&&n(o.createElement);t.exports=function(e){return i?o.createElement(e):{}}},{"./_global":25,"./_is-object":34}],17:[function(e,t,r){t.exports="constructor,hasOwnProperty,isPrototypeOf,propertyIsEnumerable,toLocaleString,toString,valueOf".split(",")},{}],18:[function(e,t,r){var n=e("./_object-keys"),o=e("./_object-gops"),i=e("./_object-pie");t.exports=function(e){var t=n(e),r=o.f;if(r)for(var s,c=r(e),a=i.f,u=0;c.length>u;)a.call(e,s=c[u++])&&t.push(s);return t}},{"./_object-gops":50,"./_object-keys":53,"./_object-pie":54}],19:[function(e,t,r){var n=e("./_global"),o=e("./_core"),i=e("./_hide"),s=e("./_redefine"),c=e("./_ctx"),a=function(e,t,r){var u,l,f,d,p=e&a.F,h=e&a.G,_=e&a.S,y=e&a.P,g=e&a.B,m=h?n:_?n[t]||(n[t]={}):(n[t]||{}).prototype,v=h?o:o[t]||(o[t]={}),b=v.prototype||(v.prototype={});for(u in h&&(r=t),r)f=((l=!p&&m&&void 0!==m[u])?m:r)[u],d=g&&l?c(f,n):y&&"function"==typeof f?c(Function.call,f):f,m&&s(m,u,f,e&a.U),v[u]!=f&&i(v,u,d),y&&b[u]!=f&&(b[u]=f)};n.core=o,a.F=1,a.G=2,a.S=4,a.P=8,a.B=16,a.W=32,a.U=64,a.R=128,t.exports=a},{"./_core":11,"./_ctx":13,"./_global":25,"./_hide":27,"./_redefine":58}],20:[function(e,t,r){var n=e("./_wks")("match");t.exports=function(e){var t=/./;try{"/./"[e](t)}catch(r){try{return t[n]=!1,!"/./"[e](t)}catch(e){}}return!0}},{"./_wks":80}],21:[function(e,t,r){t.exports=function(e){try{return!!e()}catch(e){return!0}}},{}],22:[function(e,t,r){"use strict";e("./es6.regexp.exec");var n=e("./_redefine"),o=e("./_hide"),i=e("./_fails"),s=e("./_defined"),c=e("./_wks"),a=e("./_regexp-exec"),u=c("species"),l=!i((function(){var e=/./;return e.exec=function(){var e=[];return e.groups={a:"7"},e},"7"!=="".replace(e,"$")})),f=function(){var e=/(?:)/,t=e.exec;e.exec=function(){return t.apply(this,arguments)};var r="ab".split(e);return 2===r.length&&"a"===r[0]&&"b"===r[1]}();t.exports=function(e,t,r){var d=c(e),p=!i((function(){var t={};return t[d]=function(){return 7},7!=""[e](t)})),h=p?!i((function(){var t=!1,r=/a/;return r.exec=function(){return t=!0,null},"split"===e&&(r.constructor={},r.constructor[u]=function(){return r}),r[d](""),!t})):void 0;if(!p||!h||"replace"===e&&!l||"split"===e&&!f){var _=/./[d],y=r(s,d,""[e],(function(e,t,r,n,o){return t.exec===a?p&&!o?{done:!0,value:_.call(t,r,n)}:{done:!0,value:e.call(r,t,n)}:{done:!1}})),g=y[0],m=y[1];n(String.prototype,e,g),o(RegExp.prototype,d,2==t?function(e,t){return m.call(e,this,t)}:function(e){return m.call(e,this)})}}},{"./_defined":14,"./_fails":21,"./_hide":27,"./_redefine":58,"./_regexp-exec":60,"./_wks":80,"./es6.regexp.exec":92}],23:[function(e,t,r){"use strict";var n=e("./_an-object");t.exports=function(){var e=n(this),t="";return e.global&&(t+="g"),e.ignoreCase&&(t+="i"),e.multiline&&(t+="m"),e.unicode&&(t+="u"),e.sticky&&(t+="y"),t}},{"./_an-object":4}],24:[function(e,t,r){t.exports=e("./_shared")("native-function-to-string",Function.toString)},{"./_shared":65}],25:[function(e,t,r){var n=t.exports="undefined"!=typeof window&&window.Math==Math?window:"undefined"!=typeof self&&self.Math==Math?self:Function("return this")();"number"==typeof __g&&(__g=n)},{}],26:[function(e,t,r){var n={}.hasOwnProperty;t.exports=function(e,t){return n.call(e,t)}},{}],27:[function(e,t,r){var n=e("./_object-dp"),o=e("./_property-desc");t.exports=e("./_descriptors")?function(e,t,r){return n.f(e,t,o(1,r))}:function(e,t,r){return e[t]=r,e}},{"./_descriptors":15,"./_object-dp":45,"./_property-desc":57}],28:[function(e,t,r){var n=e("./_global").document;t.exports=n&&n.documentElement},{"./_global":25}],29:[function(e,t,r){t.exports=!e("./_descriptors")&&!e("./_fails")((function(){return 7!=Object.defineProperty(e("./_dom-create")("div"),"a",{get:function(){return 7}}).a}))},{"./_descriptors":15,"./_dom-create":16,"./_fails":21}],30:[function(e,t,r){var n=e("./_is-object"),o=e("./_set-proto").set;t.exports=function(e,t,r){var i,s=t.constructor;return s!==r&&"function"==typeof s&&(i=s.prototype)!==r.prototype&&n(i)&&o&&o(e,i),e}},{"./_is-object":34,"./_set-proto":61}],31:[function(e,t,r){var n=e("./_cof");t.exports=Object("z").propertyIsEnumerable(0)?Object:function(e){return"String"==n(e)?e.split(""):Object(e)}},{"./_cof":10}],32:[function(e,t,r){var n=e("./_iterators"),o=e("./_wks")("iterator"),i=Array.prototype;t.exports=function(e){return void 0!==e&&(n.Array===e||i[o]===e)}},{"./_iterators":41,"./_wks":80}],33:[function(e,t,r){var n=e("./_cof");t.exports=Array.isArray||function(e){return"Array"==n(e)}},{"./_cof":10}],34:[function(e,t,r){t.exports=function(e){return"object"==typeof e?null!==e:"function"==typeof e}},{}],35:[function(e,t,r){var n=e("./_is-object"),o=e("./_cof"),i=e("./_wks")("match");t.exports=function(e){var t;return n(e)&&(void 0!==(t=e[i])?!!t:"RegExp"==o(e))}},{"./_cof":10,"./_is-object":34,"./_wks":80}],36:[function(e,t,r){var n=e("./_an-object");t.exports=function(e,t,r,o){try{return o?t(n(r)[0],r[1]):t(r)}catch(t){var i=e.return;throw void 0!==i&&n(i.call(e)),t}}},{"./_an-object":4}],37:[function(e,t,r){"use strict";var n=e("./_object-create"),o=e("./_property-desc"),i=e("./_set-to-string-tag"),s={};e("./_hide")(s,e("./_wks")("iterator"),(function(){return this})),t.exports=function(e,t,r){e.prototype=n(s,{next:o(1,r)}),i(e,t+" Iterator")}},{"./_hide":27,"./_object-create":44,"./_property-desc":57,"./_set-to-string-tag":63,"./_wks":80}],38:[function(e,t,r){"use strict";var n=e("./_library"),o=e("./_export"),i=e("./_redefine"),s=e("./_hide"),c=e("./_iterators"),a=e("./_iter-create"),u=e("./_set-to-string-tag"),l=e("./_object-gpo"),f=e("./_wks")("iterator"),d=!([].keys&&"next"in[].keys()),p=function(){return this};t.exports=function(e,t,r,h,_,y,g){a(r,t,h);var m,v,b,j=function(e){if(!d&&e in S)return S[e];switch(e){case"keys":case"values":return function(){return new r(this,e)}}return function(){return new r(this,e)}},w=t+" Iterator",x="values"==_,k=!1,S=e.prototype,O=S[f]||S["@@iterator"]||_&&S[_],R=O||j(_),E=_?x?j("entries"):R:void 0,L="Array"==t&&S.entries||O;if(L&&(b=l(L.call(new e)))!==Object.prototype&&b.next&&(u(b,w,!0),n||"function"==typeof b[f]||s(b,f,p)),x&&O&&"values"!==O.name&&(k=!0,R=function(){return O.call(this)}),n&&!g||!d&&!k&&S[f]||s(S,f,R),c[t]=R,c[w]=p,_)if(m={values:x?R:j("values"),keys:y?R:j("keys"),entries:E},g)for(v in m)v in S||i(S,v,m[v]);else o(o.P+o.F*(d||k),t,m);return m}},{"./_export":19,"./_hide":27,"./_iter-create":37,"./_iterators":41,"./_library":42,"./_object-gpo":51,"./_redefine":58,"./_set-to-string-tag":63,"./_wks":80}],39:[function(e,t,r){var n=e("./_wks")("iterator"),o=!1;try{var i=[7][n]();i.return=function(){o=!0},Array.from(i,(function(){throw 2}))}catch(e){}t.exports=function(e,t){if(!t&&!o)return!1;var r=!1;try{var i=[7],s=i[n]();s.next=function(){return{done:r=!0}},i[n]=function(){return s},e(i)}catch(e){}return r}},{"./_wks":80}],40:[function(e,t,r){t.exports=function(e,t){return{value:t,done:!!e}}},{}],41:[function(e,t,r){t.exports={}},{}],42:[function(e,t,r){t.exports=!1},{}],43:[function(e,t,r){var n=e("./_uid")("meta"),o=e("./_is-object"),i=e("./_has"),s=e("./_object-dp").f,c=0,a=Object.isExtensible||function(){return!0},u=!e("./_fails")((function(){return a(Object.preventExtensions({}))})),l=function(e){s(e,n,{value:{i:"O"+ ++c,w:{}}})},f=t.exports={KEY:n,NEED:!1,fastKey:function(e,t){if(!o(e))return"symbol"==typeof e?e:("string"==typeof e?"S":"P")+e;if(!i(e,n)){if(!a(e))return"F";if(!t)return"E";l(e)}return e[n].i},getWeak:function(e,t){if(!i(e,n)){if(!a(e))return!0;if(!t)return!1;l(e)}return e[n].w},onFreeze:function(e){return u&&f.NEED&&a(e)&&!i(e,n)&&l(e),e}}},{"./_fails":21,"./_has":26,"./_is-object":34,"./_object-dp":45,"./_uid":77}],44:[function(e,t,r){var n=e("./_an-object"),o=e("./_object-dps"),i=e("./_enum-bug-keys"),s=e("./_shared-key")("IE_PROTO"),c=function(){},a=function(){var t,r=e("./_dom-create")("iframe"),n=i.length;for(r.style.display="none",e("./_html").appendChild(r),r.src="javascript:",(t=r.contentWindow.document).open(),t.write("