diff --git a/.gitignore b/.gitignore index befc898b..24093e5b 100644 --- a/.gitignore +++ b/.gitignore @@ -37,3 +37,9 @@ local.properties # ctags .tags* + +# Lang +glances.pot + +# Sphinx +_build diff --git a/NEWS b/NEWS index d814d405..f411f0f3 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,12 @@ +<<<<<<< HEAD +Version 1.7.7 +============= + + * Fix CVS export [issue #348] + * Adapt to PSUtil 2.1.1 + * Compatibility with Python 3.4 + * Improve German update +======= ============================================================================== Glances Version 2.x ============================================================================== @@ -62,6 +71,40 @@ Version 2.0 Glances Version 1.x ============================================================================== +Version 1.7.7 +============= + +* Fix CVS export [issue #348] +* Adapt to PSUtil 2.1.1 +* Compatibility with Python 3.4 +* Improve German update +>>>>>>> release/v2.0 + +Version 1.7.6 +============= + +<<<<<<< HEAD + * Adapt to psutil 2.0.0 API + * Fixed psutil 0.5.x support on Windows + * Fix help screen in 80x24 terminal size + * Implement toggle of process list display ('z' key) +======= + * Adapt to psutil 2.0.0 API + * Fixed psutil 0.5.x support on Windows + * Fix help screen in 80x24 terminal size + * Implement toggle of process list display ('z' key) +>>>>>>> release/v2.0 + +Version 1.7.5 +============= + +<<<<<<< HEAD + * Force the Pypi installer to use the PsUtil branch 1.x (#333) + +======= + * Force the Pypi installer to use the PsUtil branch 1.x (#333) + +>>>>>>> release/v2.0 Version 1.7.4 ============= @@ -116,13 +159,14 @@ Version 1.7 * Add a uninstall script * Add getNetTimeSinceLastUpdate() getDiskTimeSinceLastUpdate() and getProcessDiskTimeSinceLastUpdate() in the API * Add more translation: Italien, Chinese - * and last but not least... up to 100 hundred bugs corrected / software and docs improvments + * and last but not least... up to 100 hundred bugs corrected / software and + * docs improvements Version 1.6.1 ============= * Add per-user settings (configuration file) support - * Add -z/--nobold option for better appearence under Solarized terminal + * Add -z/--nobold option for better appearance under Solarized terminal * Key 'u' shows cumulative net traffic * Work in improving autoUnit * Take into account the number of core in the CPU process limit @@ -263,7 +307,7 @@ Version 1.3.4 Version 1.3.3 ============= - * Automaticaly swith between process short and long name + * Automatically swith between process short and long name * Center the host / system information * Always put the hour/date in the bottom/right * Correct a bug if there is a lot of Disk/IO diff --git a/README.rst b/README.rst index d84c7c0e..d6140e5f 100644 --- a/README.rst +++ b/README.rst @@ -18,7 +18,8 @@ Glances - An eye on your system .. image:: https://raw.github.com/nicolargo/glances/master/docs/images/glances-white-256.png :width: 128 -**Glances** is a cross-platform curses-based system monitoring tool written in Python. +**Glances** is a cross-platform curses-based system monitoring tool +written in Python. It uses the `psutil`_ library to get information from your system. @@ -27,16 +28,29 @@ It uses the `psutil`_ library to get information from your system. Requirements ============ +<<<<<<< HEAD +- ``python >= 2.6`` (tested with version 2.6, 2.7, 3.2, 3.3, 3.4) +- ``psutil >= 0.5.1`` (recommended version >= 2.0.0) +======= - ``python >= 2.6`` (tested with version 2.6, 2.7, 3.3, 3.4) - ``psutil >= 2.0.0`` +>>>>>>> release/v2.0 - ``setuptools`` Optional dependencies: -- ``bottle`` (for Web Server mode) -- ``py3sensors`` (for hardware monitoring support) [Linux-only] +<<<<<<< HEAD +- ``jinja2`` (for HTML output) +- ``pysensors`` (for HW monitoring support) [Linux-only] - ``hddtemp`` (for HDD temperature monitoring support) - ``batinfo`` (for battery monitoring support) [Linux-only] +======= +- ``bottle`` (for Web server mode) +- ``py3sensors`` (for hardware monitoring support) [Linux-only] +- ``hddtemp`` (for HDD temperature monitoring support) [Linux-only] +- ``batinfo`` (for battery monitoring support) [Linux-only] +- ``pysnmp`` (for SNMP support) +>>>>>>> release/v2.0 Installation ============ @@ -44,7 +58,8 @@ Installation PyPI: The simple way -------------------- -Glances is on `PyPI`_. By using Pypi, you are sure to have the latest stable version. +Glances is on `PyPI`_. By using PyPI, you are sure to have the latest +stable version. To install, simply use `pip`_: @@ -52,8 +67,13 @@ To install, simply use `pip`_: pip install Glances -*Note*: Python headers are required to install PSutil. For example, +<<<<<<< HEAD +*Note*: Python headers are required to install psutil. +For example, on Debian/Ubuntu you need to install first the *python-dev* package. +======= +*Note*: Python headers are required to install psutil. For example, on Debian/Ubuntu you need to install first the *python-dev* package. +>>>>>>> release/v2.0 To upgrade Glances to the latest version: @@ -64,7 +84,11 @@ To upgrade Glances to the latest version: GNU/Linux --------- +<<<<<<< HEAD +At the moment, packages exist for the following distributions: +======= At the moment, packages exist for the following GNU/Linux distributions: +>>>>>>> release/v2.0 - Arch Linux - Debian (Testing/Sid) @@ -121,9 +145,21 @@ MacPorts Windows ------- +<<<<<<< HEAD Glances proposes a Windows client based on the `colorconsole`_ Python library. +Glances version < 1.7.2 only works in server mode. -To install Glances on Windows OS, you have to follow these steps: +Thanks to Nicolas Bourges, a Windows installer is available: + +- Glances-1.7.2-win32.msi_ (32-bit, MD5: dba4f6cc9f47b6806ffaeb665c093270) + +Otherwise, you have to follow these steps: +======= +Glances proposes a Windows client based on the `colorconsole`_ Python +library. + +To install Glances on Windows, you have to follow these steps: +>>>>>>> release/v2.0 - Install Python for Windows: http://www.python.org/getit/ - Install the psutil library: https://pypi.python.org/pypi?:action=display&name=psutil#downloads @@ -142,8 +178,13 @@ To install Glances version X.Y from source: $ cd glances-* # python setup.py install +<<<<<<< HEAD +*Note*: Python headers are required to install psutil. +For example, on Debian/Ubuntu you need to install first the *python-dev* package. +======= *Note*: Python headers are required to install psutil. For example, on Debian/Ubuntu you need to install first the *python-dev* package. +>>>>>>> release/v2.0 Puppet ------ @@ -166,7 +207,7 @@ For the Web server mode, run: $ glances -w -and enter the URL http://:61208 in your favorite Web Browser. +and enter the URL ``http://:61208`` in your favorite web browser. For the client/server mode, run: @@ -206,7 +247,6 @@ LGPL. See ``COPYING`` for more details. .. _pip: http://www.pip-installer.org/ .. _Homebrew: http://brew.sh/ .. _MacPorts: https://www.macports.org/ -.. _Glances-1.7.2-win32.msi: http://glances.s3.amazonaws.com/Glances-1.7.2-win32.msi .. _colorconsole: https://pypi.python.org/pypi/colorconsole .. _Puppet: https://puppetlabs.com/puppet/what-is-puppet/ .. _glances-doc: https://github.com/nicolargo/glances/blob/master/docs/glances-doc.rst diff --git a/docs/_build/doctrees/environment.pickle b/docs/_build/doctrees/environment.pickle deleted file mode 100644 index 55ef87fd..00000000 Binary files a/docs/_build/doctrees/environment.pickle and /dev/null differ diff --git a/docs/_build/doctrees/glances-doc.doctree b/docs/_build/doctrees/glances-doc.doctree deleted file mode 100644 index 812de66b..00000000 Binary files a/docs/_build/doctrees/glances-doc.doctree and /dev/null differ diff --git a/docs/_build/doctrees/index.doctree b/docs/_build/doctrees/index.doctree deleted file mode 100644 index 20624f9a..00000000 Binary files a/docs/_build/doctrees/index.doctree and /dev/null differ diff --git a/docs/_build/html/.buildinfo b/docs/_build/html/.buildinfo deleted file mode 100644 index 32820bba..00000000 --- a/docs/_build/html/.buildinfo +++ /dev/null @@ -1,4 +0,0 @@ -# Sphinx build info version 1 -# This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done. -config: 88f9709ac94d939db26f5322044ea5df -tags: fbb0d17656682115ca4d033fb2f83ba1 diff --git a/docs/_build/html/_images/battery.png b/docs/_build/html/_images/battery.png deleted file mode 100644 index 238b7b94..00000000 Binary files a/docs/_build/html/_images/battery.png and /dev/null differ diff --git a/docs/_build/html/_images/client-connected.png b/docs/_build/html/_images/client-connected.png deleted file mode 100644 index 29dac50a..00000000 Binary files a/docs/_build/html/_images/client-connected.png and /dev/null differ diff --git a/docs/_build/html/_images/client-disconnected.png b/docs/_build/html/_images/client-disconnected.png deleted file mode 100644 index 8bce9c28..00000000 Binary files a/docs/_build/html/_images/client-disconnected.png and /dev/null differ diff --git a/docs/_build/html/_images/cpu-wide.png b/docs/_build/html/_images/cpu-wide.png deleted file mode 100644 index 9c1032a0..00000000 Binary files a/docs/_build/html/_images/cpu-wide.png and /dev/null differ diff --git a/docs/_build/html/_images/cpu.png b/docs/_build/html/_images/cpu.png deleted file mode 100644 index 1d5093d3..00000000 Binary files a/docs/_build/html/_images/cpu.png and /dev/null differ diff --git a/docs/_build/html/_images/diskio.png b/docs/_build/html/_images/diskio.png deleted file mode 100644 index 67661593..00000000 Binary files a/docs/_build/html/_images/diskio.png and /dev/null differ diff --git a/docs/_build/html/_images/footer.png b/docs/_build/html/_images/footer.png deleted file mode 100644 index 1145927d..00000000 Binary files a/docs/_build/html/_images/footer.png and /dev/null differ diff --git a/docs/_build/html/_images/fs.png b/docs/_build/html/_images/fs.png deleted file mode 100644 index ec9a7622..00000000 Binary files a/docs/_build/html/_images/fs.png and /dev/null differ diff --git a/docs/_build/html/_images/hddtemp.png b/docs/_build/html/_images/hddtemp.png deleted file mode 100644 index e238efad..00000000 Binary files a/docs/_build/html/_images/hddtemp.png and /dev/null differ diff --git a/docs/_build/html/_images/header.png b/docs/_build/html/_images/header.png deleted file mode 100644 index 5b381833..00000000 Binary files a/docs/_build/html/_images/header.png and /dev/null differ diff --git a/docs/_build/html/_images/load.png b/docs/_build/html/_images/load.png deleted file mode 100644 index 48cae129..00000000 Binary files a/docs/_build/html/_images/load.png and /dev/null differ diff --git a/docs/_build/html/_images/logs.png b/docs/_build/html/_images/logs.png deleted file mode 100644 index d51f2be8..00000000 Binary files a/docs/_build/html/_images/logs.png and /dev/null differ diff --git a/docs/_build/html/_images/mem-wide.png b/docs/_build/html/_images/mem-wide.png deleted file mode 100644 index 570c022f..00000000 Binary files a/docs/_build/html/_images/mem-wide.png and /dev/null differ diff --git a/docs/_build/html/_images/mem.png b/docs/_build/html/_images/mem.png deleted file mode 100644 index 5128c6e8..00000000 Binary files a/docs/_build/html/_images/mem.png and /dev/null differ diff --git a/docs/_build/html/_images/monitored.png b/docs/_build/html/_images/monitored.png deleted file mode 100644 index 222425c6..00000000 Binary files a/docs/_build/html/_images/monitored.png and /dev/null differ diff --git a/docs/_build/html/_images/network.png b/docs/_build/html/_images/network.png deleted file mode 100644 index 3336afd1..00000000 Binary files a/docs/_build/html/_images/network.png and /dev/null differ diff --git a/docs/_build/html/_images/per-cpu.png b/docs/_build/html/_images/per-cpu.png deleted file mode 100644 index 16601447..00000000 Binary files a/docs/_build/html/_images/per-cpu.png and /dev/null differ diff --git a/docs/_build/html/_images/processlist-wide.png b/docs/_build/html/_images/processlist-wide.png deleted file mode 100644 index aa9b2446..00000000 Binary files a/docs/_build/html/_images/processlist-wide.png and /dev/null differ diff --git a/docs/_build/html/_images/processlist.png b/docs/_build/html/_images/processlist.png deleted file mode 100644 index 460e0f8c..00000000 Binary files a/docs/_build/html/_images/processlist.png and /dev/null differ diff --git a/docs/_build/html/_images/screenshot-wide.png b/docs/_build/html/_images/screenshot-wide.png deleted file mode 100644 index e0e3a510..00000000 Binary files a/docs/_build/html/_images/screenshot-wide.png and /dev/null differ diff --git a/docs/_build/html/_images/screenshot.png b/docs/_build/html/_images/screenshot.png deleted file mode 100644 index 1940adb8..00000000 Binary files a/docs/_build/html/_images/screenshot.png and /dev/null differ diff --git a/docs/_build/html/_images/sensors.png b/docs/_build/html/_images/sensors.png deleted file mode 100644 index 8b17c0af..00000000 Binary files a/docs/_build/html/_images/sensors.png and /dev/null differ diff --git a/docs/_build/html/_sources/glances-doc.txt b/docs/_build/html/_sources/glances-doc.txt deleted file mode 100644 index b3549798..00000000 --- a/docs/_build/html/_sources/glances-doc.txt +++ /dev/null @@ -1,529 +0,0 @@ -======= -Glances -======= - -This manual describes *Glances* version 1.7.3. - -Copyright © 2012-2013 Nicolas Hennion - -November 2013 - -.. contents:: Table of Contents - -Introduction -============ - -Glances is a cross-platform curses-based monitoring tool which aims to -present a maximum of information in a minimum of space, ideally to fit -in a classical 80x24 terminal or higher to have additional information. - -Glances can adapt dynamically the displayed information depending on the -terminal size. It can also work in a client/server mode for remote monitoring. - -Glances is written in Python and uses the `psutil`_ library to get information from your system. - -Console (80x24) - -.. image:: images/screenshot.png - -Full view (>80x24) - -.. image:: images/screenshot-wide.png - -Usage -===== - -Standalone mode ---------------- - -Simply run: - -.. code-block:: console - - $ glances - -Client/Server mode ------------------- - -If you want to remotely monitor a machine, called ``server``, from another one, called ``client``, -just run on the server: - -.. code-block:: console - - server$ glances -s - -and on the client: - -.. code-block:: console - - client$ glances -c @server - -where ``@server`` is the IP address or hostname of the server. - -In server mode, you can set the bind address ``-B ADDRESS`` and listening TCP port ``-p PORT``. - -In client mode, you can set the TCP port of the server ``-p PORT``. - -Default binding address is ``0.0.0.0`` (Glances will listen on all the network interfaces) and TCP port is ``61209``. - -In client/server mode, limits are set by the server side. - -You can also set a password to access to the server ``-P password``. - -Glances is ``IPv6`` compatible. Just use the ``-B ::`` option to bind to all IPv6 addresses. - -Command reference -================= - -Command-line options --------------------- - --b Display network rate in Byte per second (default: bit per second) --B IP Bind server to the given IPv4/IPv6 address or hostname --c IP Connect to a Glances server by IPv4/IPv6 address or hostname --C FILE Path to the configuration file --d Disable disk I/O module --e Enable sensors module (requires pysensors, Linux-only) --f FILE Set the HTML output folder or CSV file --h Display the help and exit --m Disable mount module --n Disable network module --o OUTPUT Define additional output (available: HTML or CSV) --p PORT Define the client/server TCP port (default: 61209) --P PASSWORD Define a client/server password ---password Define a client/server password from the prompt --r Disable process list (for low CPU consumption) --s Run Glances in server mode --t SECONDS Set refresh time in seconds (default: 3 sec) --v Display the version and exit --y Enable hddtemp module (requires hddtemp) --z Do not use the bold color attribute --1 Start Glances in per-CPU mode - -Interactive commands --------------------- - -The following commands (key pressed) are supported while in Glances: - - -``a`` - Sort process list automatically - - - If CPU iowait ``>60%``, sort processes by I/O read and write - - If CPU ``>70%``, sort processes by CPU usage - - If MEM ``>70%``, sort processes by memory usage -``b`` - Switch between bit/s or Byte/s for network I/O -``c`` - Sort processes by CPU usage -``d`` - Show/hide disk I/O stats -``f`` - Show/hide file system stats -``h`` - Show/hide the help screen -``i`` - Sort processes by I/O rate (may need root privileges on some OSes) -``l`` - Show/hide log messages -``m`` - Sort processes by MEM usage -``n`` - Show/hide network stats -``p`` - Sort processes by name -``q`` - Quit -``s`` - Show/hide sensors stats (only available with -e flag) -``t`` - View network I/O as combination -``u`` - View cumulative network I/O -``w`` - Delete finished warning log messages -``x`` - Delete finished warning and critical log messages -``y`` - Show/hide hddtemp stats (only available with -y flag) -``1`` - Switch between global CPU and per-CPU stats - -Configuration -============= - -No configuration file is mandatory to use Glances. - -Furthermore a configuration file is needed for setup limits and/or monitored processes list. - -By default, the configuration file is under: - -:Linux: ``/etc/glances/glances.conf`` -:\*BSD and OS X: ``/usr/local/etc/glances/glances.conf`` -:Windows: ``%APPDATA%\glances\glances.conf`` - -On Windows XP, the ``%APPDATA%`` path is: - -.. code-block:: console - - C:\Documents and Settings\\Application Data - -Since Windows Vista and newer versions: - -.. code-block:: console - - C:\Users\\AppData\Roaming - -You can override the default configuration, located in one of the above -directories on your system, except for Windows. - -Just copy the ``glances.conf`` file to your ``$XDG_CONFIG_HOME`` directory, e.g. Linux: - -.. code-block:: console - - mkdir -p $XDG_CONFIG_HOME/glances - cp /etc/glances/glances.conf $XDG_CONFIG_HOME/glances/ - -On OS X, you should copy the configuration file to ``~/Library/Application Support/glances/``. - -Anatomy of the application -========================== - -Legend ------- - -| ``GREEN`` stat counter is ``"OK"`` -| ``BLUE`` stat counter is ``"CAREFUL"`` -| ``MAGENTA`` stat counter is ``"WARNING"`` -| ``RED`` stat counter is ``"CRITICAL"`` - -Header ------- - -.. image:: images/header.png - -The header shows the OS name, release version, platform architecture and the hostname. -On Linux, it shows also the kernel version. - -CPU ---- - -Short view: - -.. image:: images/cpu.png - -If enough horizontal space is available, extended CPU informations are displayed. - -Extended view: - -.. image:: images/cpu-wide.png - -To switch to per-CPU stats, just hit the ``1`` key: - -.. image:: images/per-cpu.png - -The CPU stats are shown as a percentage and for the configured refresh time. -The total CPU usage is displayed on the first line. - -| If user|system|nice CPU is ``<50%``, then status is set to ``"OK"`` -| If user|system|nice CPU is ``>50%``, then status is set to ``"CAREFUL"`` -| If user|system|nice CPU is ``>70%``, then status is set to ``"WARNING"`` -| If user|system|nice CPU is ``>90%``, then status is set to ``"CRITICAL"`` - -*Note*: limit values can be overwritten in the configuration file under the ``[cpu]`` section. - -Load ----- - -.. image:: images/load.png - -On the *No Sheep* blog, *Zachary Tirrell* defines the average load [1]_: - - "In short it is the average sum of the number of processes - waiting in the run-queue plus the number currently executing - over 1, 5, and 15 minute time periods." - -Glances gets the number of CPU core to adapt the alerts. -Alerts on average load are only set on 5 and 15 min. -The first line also display the number of CPU core. - -| If average load is ``<0.7*core``, then status is set to ``"OK"`` -| If average load is ``>0.7*core``, then status is set to ``"CAREFUL"`` -| If average load is ``>1*core``, then status is set to ``"WARNING"`` -| If average load is ``>5*core``, then status is set to ``"CRITICAL"`` - -*Note*: limit values can be overwritten in the configuration file under the ``[load]`` section. - -Memory ------- - -Glances uses two columns: one for the ``RAM`` and another one for the ``Swap``. - -.. image:: images/mem.png - -If enough space is available, Glances displays extended informations: - -.. image:: images/mem-wide.png - -With Glances, alerts are only set for on used memory and used swap. - -| If memory is ``<50%``, then status is set to ``"OK"`` -| If memory is ``>50%``, then status is set to ``"CAREFUL"`` -| If memory is ``>70%``, then status is set to ``"WARNING"`` -| If memory is ``>90%``, then status is set to ``"CRITICAL"`` - -*Note*: limit values can be overwritten in the configuration file under the ``[memory]`` and ``[swap]`` sections. - -Network -------- - -.. image:: images/network.png - -Glances displays the network interface bit rate. The unit is adapted -dynamically (bits per second, kbits per second, Mbits per second, etc). - -Alerts are only set if the network interface maximum speed is available. - -For example, on a 100 Mbps ethernet interface, the warning status is set -if the bit rate is higher than 70 Mbps. - -| If bit rate is ``<50%``, then status is set to ``"OK"`` -| If bit rate is ``>50%``, then status is set to ``"CAREFUL"`` -| If bit rate is ``>70%``, then status is set to ``"WARNING"`` -| If bit rate is ``>90%``, then status is set to ``"CRITICAL"`` - -Sensors -------- - -Glances can displays the sensors informations trough `lm-sensors` (only available on Linux). - -As of lm-sensors, a filter is processed in order to display temperature only: - -.. image:: images/sensors.png - - -Glances can also grab hard disk temperature through the `hddtemp` daemon (see here [2]_ to install hddtemp on your system): - -.. image:: images/hddtemp.png - -To enable the lm-sensors module: - -.. code-block:: console - - $ glances -e - -To enable the hddtemp module: - -.. code-block:: console - - $ glances -y - -There is no alert on this information. - -*Note*: limit values can be overwritten in the configuration file under the ``[temperature]`` and ``[hddtemperature]`` sections. - -Disk I/O --------- - -.. image:: images/diskio.png - -Glances displays the disk I/O throughput. The unit is adapted dynamically. - -*Note*: There is no alert on this information. - -File system ------------ - -.. image:: images/fs.png - -Glances displays the used and total file system disk space. The unit is -adapted dynamically. - -Alerts are set for used disk space: - -| If disk used is ``<50%``, then status is set to ``"OK"`` -| If disk used is ``>50%``, then status is set to ``"CAREFUL"`` -| If disk used is ``>70%``, then status is set to ``"WARNING"`` -| If disk used is ``>90%``, then status is set to ``"CRITICAL"`` - -*Note*: limit values can be overwritten in the configuration file under ``[filesystem]`` section. - -Processes list --------------- - -Compact view: - -.. image:: images/processlist.png - -Full view: - -.. image:: images/processlist-wide.png - -Three views are available for processes: - -* Processes summary -* Optional monitored processes list (new in 1.7) -* Processes list - -By default, or if you hit the ``a`` key, the processes list is automatically -sorted by CPU of memory usage. - -*Note*: limit values can be overwritten in the configuration file under the ``[process]`` section. - -The number of processes in the list is adapted to the screen size. - -``VIRT`` - Total program size (VMS) -``RES`` - Resident set size (RSS) -``CPU%`` - % of CPU used by the process -``MEM%`` - % of MEM used by the process -``PID`` - Process ID -``USER`` - User ID per process -``NI`` - Nice level of the process -``S`` - Process status -``TIME+`` - Cumulative CPU time used -``IOR/s`` - Per process IO read rate (in Byte/s) -``IOW/s`` - Per process IO write rate (in Byte/s) -``NAME`` - Process name or command line - -Process status legend: - -``R`` - running -``S`` - sleeping (may be interrupted) -``D`` - disk sleep (may not be interrupted) -``T`` - traced/stopped -``Z`` - zombie - -Monitored processes list ------------------------- - -New in version 1.7. Optional. - -The monitored processes list allows user, through the configuration file, -to group processes and quickly show if the number of running process is not good. - -.. image:: images/monitored.png - -Each item is defined by: - -* ``description``: description of the processes (max 16 chars). -* ``regex``: regular expression of the processes to monitor. -* ``command`` (optional): full path to shell command/script for extended stat. Should return a single line string. Use with caution. -* ``countmin`` (optional): minimal number of processes. A warning will be displayed if number of processes < count. -* ``countmax`` (optional): maximum number of processes. A warning will be displayed if number of processes > count. - -Up to 10 items can be defined. - -For example, if you want to monitor the Nginx processes on a Web server, the following definition should do the job: - -.. code-block:: console - - [monitor] - list_1_description=Nginx server - list_1_regex=.*nginx.* - list_1_command=nginx -v - list_1_countmin=1 - list_1_countmax=4 - -If you also want to monitor the PHP-FPM daemon processes, you should add another item: - -.. code-block:: console - - [monitor] - list_1_description=Nginx server - list_1_regex=.*nginx.* - list_1_command=nginx -v - list_1_countmin=1 - list_1_countmax=4 - list_1_description=PHP-FPM - list_1_regex=.*php-fpm.* - list_1_countmin=1 - list_1_countmax=20 - -In client/server mode, the list is defined on the server side. -A new method, called getAllMonitored, is available in the APIs and get the JSON representation of the monitored processes list. - -Alerts are set as following: - -| If number of processes is 0, then status is set to ``"CRITICAL"`` -| If number of processes is min < current < max, then status is set to ``"OK"`` -| Else status is set to ``"WARNING"`` - -Logs ----- - -.. image:: images/logs.png - -A log messages list is displayed in the bottom of the screen if (and only if): - -- at least one ``WARNING`` or ``CRITICAL`` alert was occurred -- space is available in the bottom of the console/terminal - -Each alert message displays the following information: - -1. start date -2. end date -3. alert name -4. {min/avg/max} values or number of running processes for monitored processes list alerts - -Footer ------- - -.. image:: images/footer.png - -Glances displays the current date & time and access to the embedded help screen. - -If one or mode batteries were found on your machine and if the batinfo Python library [3]_ -is installed on your system then Glances displays the available percent capacity in the middle on the footer. - -.. image:: images/battery.png - -If you have ran Glances in client mode ``-c``, you can also see if the client is connected to the server. - -If client is connected: - -.. image:: images/client-connected.png - -else: - -.. image:: images/client-disconnected.png - -On the left, you can easily see if you are connected to a Glances server. - -API documentation -================= - -Glances uses a `XML-RPC server`_ and can be used by another client software. - -API documentation is available at https://github.com/nicolargo/glances/wiki/The-Glances-API-How-To - -Support -======= - -To report a bug or a feature request use the bug tracking system at https://github.com/nicolargo/glances/issues - -Feel free to contribute! - - -.. [1] http://nosheep.net/story/defining-unix-load-average/ -.. [2] http://www.cyberciti.biz/tips/howto-monitor-hard-drive-temperature.html -.. [3] https://github.com/nicolargo/batinfo - -.. _psutil: https://code.google.com/p/psutil/ -.. _XML-RPC server: http://docs.python.org/2/library/simplexmlrpcserver.html diff --git a/docs/_build/html/_sources/index.txt b/docs/_build/html/_sources/index.txt deleted file mode 100644 index b03349f3..00000000 --- a/docs/_build/html/_sources/index.txt +++ /dev/null @@ -1,28 +0,0 @@ -Welcome to Glances's documentation! -=================================== - -**Glances** is a cross-platform curses-based monitoring tool written in Python. - -It uses the psutil library and some internal code to get information from your system. - -.. image:: https://raw.github.com/nicolargo/glances/master/docs/images/screenshot-wide.png - -Get the code ------------- - -The `source `_ is available on GitHub. - -Contents --------- - -.. toctree:: - :maxdepth: 2 - - glances-doc - -Indices and tables -================== - -* :ref:`genindex` -* :ref:`modindex` -* :ref:`search` diff --git a/docs/_build/html/_static/ajax-loader.gif b/docs/_build/html/_static/ajax-loader.gif deleted file mode 100644 index 61faf8ca..00000000 Binary files a/docs/_build/html/_static/ajax-loader.gif and /dev/null differ diff --git a/docs/_build/html/_static/basic.css b/docs/_build/html/_static/basic.css deleted file mode 100644 index 43e8bafa..00000000 --- a/docs/_build/html/_static/basic.css +++ /dev/null @@ -1,540 +0,0 @@ -/* - * basic.css - * ~~~~~~~~~ - * - * Sphinx stylesheet -- basic theme. - * - * :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. - * :license: BSD, see LICENSE for details. - * - */ - -/* -- main layout ----------------------------------------------------------- */ - -div.clearer { - clear: both; -} - -/* -- relbar ---------------------------------------------------------------- */ - -div.related { - width: 100%; - font-size: 90%; -} - -div.related h3 { - display: none; -} - -div.related ul { - margin: 0; - padding: 0 0 0 10px; - list-style: none; -} - -div.related li { - display: inline; -} - -div.related li.right { - float: right; - margin-right: 5px; -} - -/* -- sidebar --------------------------------------------------------------- */ - -div.sphinxsidebarwrapper { - padding: 10px 5px 0 10px; -} - -div.sphinxsidebar { - float: left; - width: 230px; - margin-left: -100%; - font-size: 90%; -} - -div.sphinxsidebar ul { - list-style: none; -} - -div.sphinxsidebar ul ul, -div.sphinxsidebar ul.want-points { - margin-left: 20px; - list-style: square; -} - -div.sphinxsidebar ul ul { - margin-top: 0; - margin-bottom: 0; -} - -div.sphinxsidebar form { - margin-top: 10px; -} - -div.sphinxsidebar input { - border: 1px solid #98dbcc; - font-family: sans-serif; - font-size: 1em; -} - -div.sphinxsidebar #searchbox input[type="text"] { - width: 170px; -} - -div.sphinxsidebar #searchbox input[type="submit"] { - width: 30px; -} - -img { - border: 0; -} - -/* -- search page ----------------------------------------------------------- */ - -ul.search { - margin: 10px 0 0 20px; - padding: 0; -} - -ul.search li { - padding: 5px 0 5px 20px; - background-image: url(file.png); - background-repeat: no-repeat; - background-position: 0 7px; -} - -ul.search li a { - font-weight: bold; -} - -ul.search li div.context { - color: #888; - margin: 2px 0 0 30px; - text-align: left; -} - -ul.keywordmatches li.goodmatch a { - font-weight: bold; -} - -/* -- index page ------------------------------------------------------------ */ - -table.contentstable { - width: 90%; -} - -table.contentstable p.biglink { - line-height: 150%; -} - -a.biglink { - font-size: 1.3em; -} - -span.linkdescr { - font-style: italic; - padding-top: 5px; - font-size: 90%; -} - -/* -- general index --------------------------------------------------------- */ - -table.indextable { - width: 100%; -} - -table.indextable td { - text-align: left; - vertical-align: top; -} - -table.indextable dl, table.indextable dd { - margin-top: 0; - margin-bottom: 0; -} - -table.indextable tr.pcap { - height: 10px; -} - -table.indextable tr.cap { - margin-top: 10px; - background-color: #f2f2f2; -} - -img.toggler { - margin-right: 3px; - margin-top: 3px; - cursor: pointer; -} - -div.modindex-jumpbox { - border-top: 1px solid #ddd; - border-bottom: 1px solid #ddd; - margin: 1em 0 1em 0; - padding: 0.4em; -} - -div.genindex-jumpbox { - border-top: 1px solid #ddd; - border-bottom: 1px solid #ddd; - margin: 1em 0 1em 0; - padding: 0.4em; -} - -/* -- general body styles --------------------------------------------------- */ - -a.headerlink { - visibility: hidden; -} - -h1:hover > a.headerlink, -h2:hover > a.headerlink, -h3:hover > a.headerlink, -h4:hover > a.headerlink, -h5:hover > a.headerlink, -h6:hover > a.headerlink, -dt:hover > a.headerlink { - visibility: visible; -} - -div.body p.caption { - text-align: inherit; -} - -div.body td { - text-align: left; -} - -.field-list ul { - padding-left: 1em; -} - -.first { - margin-top: 0 !important; -} - -p.rubric { - margin-top: 30px; - font-weight: bold; -} - -img.align-left, .figure.align-left, object.align-left { - clear: left; - float: left; - margin-right: 1em; -} - -img.align-right, .figure.align-right, object.align-right { - clear: right; - float: right; - margin-left: 1em; -} - -img.align-center, .figure.align-center, object.align-center { - display: block; - margin-left: auto; - margin-right: auto; -} - -.align-left { - text-align: left; -} - -.align-center { - text-align: center; -} - -.align-right { - text-align: right; -} - -/* -- sidebars -------------------------------------------------------------- */ - -div.sidebar { - margin: 0 0 0.5em 1em; - border: 1px solid #ddb; - padding: 7px 7px 0 7px; - background-color: #ffe; - width: 40%; - float: right; -} - -p.sidebar-title { - font-weight: bold; -} - -/* -- topics ---------------------------------------------------------------- */ - -div.topic { - border: 1px solid #ccc; - padding: 7px 7px 0 7px; - margin: 10px 0 10px 0; -} - -p.topic-title { - font-size: 1.1em; - font-weight: bold; - margin-top: 10px; -} - -/* -- admonitions ----------------------------------------------------------- */ - -div.admonition { - margin-top: 10px; - margin-bottom: 10px; - padding: 7px; -} - -div.admonition dt { - font-weight: bold; -} - -div.admonition dl { - margin-bottom: 0; -} - -p.admonition-title { - margin: 0px 10px 5px 0px; - font-weight: bold; -} - -div.body p.centered { - text-align: center; - margin-top: 25px; -} - -/* -- tables ---------------------------------------------------------------- */ - -table.docutils { - border: 0; - border-collapse: collapse; -} - -table.docutils td, table.docutils th { - padding: 1px 8px 1px 5px; - border-top: 0; - border-left: 0; - border-right: 0; - border-bottom: 1px solid #aaa; -} - -table.field-list td, table.field-list th { - border: 0 !important; -} - -table.footnote td, table.footnote th { - border: 0 !important; -} - -th { - text-align: left; - padding-right: 5px; -} - -table.citation { - border-left: solid 1px gray; - margin-left: 1px; -} - -table.citation td { - border-bottom: none; -} - -/* -- other body styles ----------------------------------------------------- */ - -ol.arabic { - list-style: decimal; -} - -ol.loweralpha { - list-style: lower-alpha; -} - -ol.upperalpha { - list-style: upper-alpha; -} - -ol.lowerroman { - list-style: lower-roman; -} - -ol.upperroman { - list-style: upper-roman; -} - -dl { - margin-bottom: 15px; -} - -dd p { - margin-top: 0px; -} - -dd ul, dd table { - margin-bottom: 10px; -} - -dd { - margin-top: 3px; - margin-bottom: 10px; - margin-left: 30px; -} - -dt:target, .highlighted { - background-color: #fbe54e; -} - -dl.glossary dt { - font-weight: bold; - font-size: 1.1em; -} - -.field-list ul { - margin: 0; - padding-left: 1em; -} - -.field-list p { - margin: 0; -} - -.refcount { - color: #060; -} - -.optional { - font-size: 1.3em; -} - -.versionmodified { - font-style: italic; -} - -.system-message { - background-color: #fda; - padding: 5px; - border: 3px solid red; -} - -.footnote:target { - background-color: #ffa; -} - -.line-block { - display: block; - margin-top: 1em; - margin-bottom: 1em; -} - -.line-block .line-block { - margin-top: 0; - margin-bottom: 0; - margin-left: 1.5em; -} - -.guilabel, .menuselection { - font-family: sans-serif; -} - -.accelerator { - text-decoration: underline; -} - -.classifier { - font-style: oblique; -} - -abbr, acronym { - border-bottom: dotted 1px; - cursor: help; -} - -/* -- code displays --------------------------------------------------------- */ - -pre { - overflow: auto; - overflow-y: hidden; /* fixes display issues on Chrome browsers */ -} - -td.linenos pre { - padding: 5px 0px; - border: 0; - background-color: transparent; - color: #aaa; -} - -table.highlighttable { - margin-left: 0.5em; -} - -table.highlighttable td { - padding: 0 0.5em 0 0.5em; -} - -tt.descname { - background-color: transparent; - font-weight: bold; - font-size: 1.2em; -} - -tt.descclassname { - background-color: transparent; -} - -tt.xref, a tt { - background-color: transparent; - font-weight: bold; -} - -h1 tt, h2 tt, h3 tt, h4 tt, h5 tt, h6 tt { - background-color: transparent; -} - -.viewcode-link { - float: right; -} - -.viewcode-back { - float: right; - font-family: sans-serif; -} - -div.viewcode-block:target { - margin: -1px -10px; - padding: 0 10px; -} - -/* -- math display ---------------------------------------------------------- */ - -img.math { - vertical-align: middle; -} - -div.body div.math p { - text-align: center; -} - -span.eqno { - float: right; -} - -/* -- printout stylesheet --------------------------------------------------- */ - -@media print { - div.document, - div.documentwrapper, - div.bodywrapper { - margin: 0 !important; - width: 100%; - } - - div.sphinxsidebar, - div.related, - div.footer, - #top-link { - display: none; - } -} \ No newline at end of file diff --git a/docs/_build/html/_static/comment-bright.png b/docs/_build/html/_static/comment-bright.png deleted file mode 100644 index 551517b8..00000000 Binary files a/docs/_build/html/_static/comment-bright.png and /dev/null differ diff --git a/docs/_build/html/_static/comment-close.png b/docs/_build/html/_static/comment-close.png deleted file mode 100644 index 09b54be4..00000000 Binary files a/docs/_build/html/_static/comment-close.png and /dev/null differ diff --git a/docs/_build/html/_static/comment.png b/docs/_build/html/_static/comment.png deleted file mode 100644 index 92feb52b..00000000 Binary files a/docs/_build/html/_static/comment.png and /dev/null differ diff --git a/docs/_build/html/_static/default.css b/docs/_build/html/_static/default.css deleted file mode 100644 index 21f3f509..00000000 --- a/docs/_build/html/_static/default.css +++ /dev/null @@ -1,256 +0,0 @@ -/* - * default.css_t - * ~~~~~~~~~~~~~ - * - * Sphinx stylesheet -- default theme. - * - * :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. - * :license: BSD, see LICENSE for details. - * - */ - -@import url("basic.css"); - -/* -- page layout ----------------------------------------------------------- */ - -body { - font-family: sans-serif; - font-size: 100%; - background-color: #11303d; - color: #000; - margin: 0; - padding: 0; -} - -div.document { - background-color: #1c4e63; -} - -div.documentwrapper { - float: left; - width: 100%; -} - -div.bodywrapper { - margin: 0 0 0 230px; -} - -div.body { - background-color: #ffffff; - color: #000000; - padding: 0 20px 30px 20px; -} - -div.footer { - color: #ffffff; - width: 100%; - padding: 9px 0 9px 0; - text-align: center; - font-size: 75%; -} - -div.footer a { - color: #ffffff; - text-decoration: underline; -} - -div.related { - background-color: #133f52; - line-height: 30px; - color: #ffffff; -} - -div.related a { - color: #ffffff; -} - -div.sphinxsidebar { -} - -div.sphinxsidebar h3 { - font-family: 'Trebuchet MS', sans-serif; - color: #ffffff; - font-size: 1.4em; - font-weight: normal; - margin: 0; - padding: 0; -} - -div.sphinxsidebar h3 a { - color: #ffffff; -} - -div.sphinxsidebar h4 { - font-family: 'Trebuchet MS', sans-serif; - color: #ffffff; - font-size: 1.3em; - font-weight: normal; - margin: 5px 0 0 0; - padding: 0; -} - -div.sphinxsidebar p { - color: #ffffff; -} - -div.sphinxsidebar p.topless { - margin: 5px 10px 10px 10px; -} - -div.sphinxsidebar ul { - margin: 10px; - padding: 0; - color: #ffffff; -} - -div.sphinxsidebar a { - color: #98dbcc; -} - -div.sphinxsidebar input { - border: 1px solid #98dbcc; - font-family: sans-serif; - font-size: 1em; -} - - - -/* -- hyperlink styles ------------------------------------------------------ */ - -a { - color: #355f7c; - text-decoration: none; -} - -a:visited { - color: #355f7c; - text-decoration: none; -} - -a:hover { - text-decoration: underline; -} - - - -/* -- body styles ----------------------------------------------------------- */ - -div.body h1, -div.body h2, -div.body h3, -div.body h4, -div.body h5, -div.body h6 { - font-family: 'Trebuchet MS', sans-serif; - background-color: #f2f2f2; - font-weight: normal; - color: #20435c; - border-bottom: 1px solid #ccc; - margin: 20px -20px 10px -20px; - padding: 3px 0 3px 10px; -} - -div.body h1 { margin-top: 0; font-size: 200%; } -div.body h2 { font-size: 160%; } -div.body h3 { font-size: 140%; } -div.body h4 { font-size: 120%; } -div.body h5 { font-size: 110%; } -div.body h6 { font-size: 100%; } - -a.headerlink { - color: #c60f0f; - font-size: 0.8em; - padding: 0 4px 0 4px; - text-decoration: none; -} - -a.headerlink:hover { - background-color: #c60f0f; - color: white; -} - -div.body p, div.body dd, div.body li { - text-align: justify; - line-height: 130%; -} - -div.admonition p.admonition-title + p { - display: inline; -} - -div.admonition p { - margin-bottom: 5px; -} - -div.admonition pre { - margin-bottom: 5px; -} - -div.admonition ul, div.admonition ol { - margin-bottom: 5px; -} - -div.note { - background-color: #eee; - border: 1px solid #ccc; -} - -div.seealso { - background-color: #ffc; - border: 1px solid #ff6; -} - -div.topic { - background-color: #eee; -} - -div.warning { - background-color: #ffe4e4; - border: 1px solid #f66; -} - -p.admonition-title { - display: inline; -} - -p.admonition-title:after { - content: ":"; -} - -pre { - padding: 5px; - background-color: #eeffcc; - color: #333333; - line-height: 120%; - border: 1px solid #ac9; - border-left: none; - border-right: none; -} - -tt { - background-color: #ecf0f3; - padding: 0 1px 0 1px; - font-size: 0.95em; -} - -th { - background-color: #ede; -} - -.warning tt { - background: #efc2c2; -} - -.note tt { - background: #d6d6d6; -} - -.viewcode-back { - font-family: sans-serif; -} - -div.viewcode-block:target { - background-color: #f4debf; - border-top: 1px solid #ac9; - border-bottom: 1px solid #ac9; -} \ No newline at end of file diff --git a/docs/_build/html/_static/doctools.js b/docs/_build/html/_static/doctools.js deleted file mode 100644 index d4619fdf..00000000 --- a/docs/_build/html/_static/doctools.js +++ /dev/null @@ -1,247 +0,0 @@ -/* - * doctools.js - * ~~~~~~~~~~~ - * - * Sphinx JavaScript utilities for all documentation. - * - * :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. - * :license: BSD, see LICENSE for details. - * - */ - -/** - * select a different prefix for underscore - */ -$u = _.noConflict(); - -/** - * make the code below compatible with browsers without - * an installed firebug like debugger -if (!window.console || !console.firebug) { - var names = ["log", "debug", "info", "warn", "error", "assert", "dir", - "dirxml", "group", "groupEnd", "time", "timeEnd", "count", "trace", - "profile", "profileEnd"]; - window.console = {}; - for (var i = 0; i < names.length; ++i) - window.console[names[i]] = function() {}; -} - */ - -/** - * small helper function to urldecode strings - */ -jQuery.urldecode = function(x) { - return decodeURIComponent(x).replace(/\+/g, ' '); -} - -/** - * small helper function to urlencode strings - */ -jQuery.urlencode = encodeURIComponent; - -/** - * This function returns the parsed url parameters of the - * current request. Multiple values per key are supported, - * it will always return arrays of strings for the value parts. - */ -jQuery.getQueryParameters = function(s) { - if (typeof s == 'undefined') - s = document.location.search; - var parts = s.substr(s.indexOf('?') + 1).split('&'); - var result = {}; - for (var i = 0; i < parts.length; i++) { - var tmp = parts[i].split('=', 2); - var key = jQuery.urldecode(tmp[0]); - var value = jQuery.urldecode(tmp[1]); - if (key in result) - result[key].push(value); - else - result[key] = [value]; - } - return result; -}; - -/** - * small function to check if an array contains - * a given item. - */ -jQuery.contains = function(arr, item) { - for (var i = 0; i < arr.length; i++) { - if (arr[i] == item) - return true; - } - return false; -}; - -/** - * highlight a given string on a jquery object by wrapping it in - * span elements with the given class name. - */ -jQuery.fn.highlightText = function(text, className) { - function highlight(node) { - if (node.nodeType == 3) { - var val = node.nodeValue; - var pos = val.toLowerCase().indexOf(text); - if (pos >= 0 && !jQuery(node.parentNode).hasClass(className)) { - var span = document.createElement("span"); - span.className = className; - span.appendChild(document.createTextNode(val.substr(pos, text.length))); - node.parentNode.insertBefore(span, node.parentNode.insertBefore( - document.createTextNode(val.substr(pos + text.length)), - node.nextSibling)); - node.nodeValue = val.substr(0, pos); - } - } - else if (!jQuery(node).is("button, select, textarea")) { - jQuery.each(node.childNodes, function() { - highlight(this); - }); - } - } - return this.each(function() { - highlight(this); - }); -}; - -/** - * Small JavaScript module for the documentation. - */ -var Documentation = { - - init : function() { - this.fixFirefoxAnchorBug(); - this.highlightSearchWords(); - this.initIndexTable(); - }, - - /** - * i18n support - */ - TRANSLATIONS : {}, - PLURAL_EXPR : function(n) { return n == 1 ? 0 : 1; }, - LOCALE : 'unknown', - - // gettext and ngettext don't access this so that the functions - // can safely bound to a different name (_ = Documentation.gettext) - gettext : function(string) { - var translated = Documentation.TRANSLATIONS[string]; - if (typeof translated == 'undefined') - return string; - return (typeof translated == 'string') ? translated : translated[0]; - }, - - ngettext : function(singular, plural, n) { - var translated = Documentation.TRANSLATIONS[singular]; - if (typeof translated == 'undefined') - return (n == 1) ? singular : plural; - return translated[Documentation.PLURALEXPR(n)]; - }, - - addTranslations : function(catalog) { - for (var key in catalog.messages) - this.TRANSLATIONS[key] = catalog.messages[key]; - this.PLURAL_EXPR = new Function('n', 'return +(' + catalog.plural_expr + ')'); - this.LOCALE = catalog.locale; - }, - - /** - * add context elements like header anchor links - */ - addContextElements : function() { - $('div[id] > :header:first').each(function() { - $('\u00B6'). - attr('href', '#' + this.id). - attr('title', _('Permalink to this headline')). - appendTo(this); - }); - $('dt[id]').each(function() { - $('\u00B6'). - attr('href', '#' + this.id). - attr('title', _('Permalink to this definition')). - appendTo(this); - }); - }, - - /** - * workaround a firefox stupidity - */ - fixFirefoxAnchorBug : function() { - if (document.location.hash && $.browser.mozilla) - window.setTimeout(function() { - document.location.href += ''; - }, 10); - }, - - /** - * highlight the search words provided in the url in the text - */ - highlightSearchWords : function() { - var params = $.getQueryParameters(); - var terms = (params.highlight) ? params.highlight[0].split(/\s+/) : []; - if (terms.length) { - var body = $('div.body'); - window.setTimeout(function() { - $.each(terms, function() { - body.highlightText(this.toLowerCase(), 'highlighted'); - }); - }, 10); - $('') - .appendTo($('#searchbox')); - } - }, - - /** - * init the domain index toggle buttons - */ - initIndexTable : function() { - var togglers = $('img.toggler').click(function() { - var src = $(this).attr('src'); - var idnum = $(this).attr('id').substr(7); - $('tr.cg-' + idnum).toggle(); - if (src.substr(-9) == 'minus.png') - $(this).attr('src', src.substr(0, src.length-9) + 'plus.png'); - else - $(this).attr('src', src.substr(0, src.length-8) + 'minus.png'); - }).css('display', ''); - if (DOCUMENTATION_OPTIONS.COLLAPSE_INDEX) { - togglers.click(); - } - }, - - /** - * helper function to hide the search marks again - */ - hideSearchWords : function() { - $('#searchbox .highlight-link').fadeOut(300); - $('span.highlighted').removeClass('highlighted'); - }, - - /** - * make the url absolute - */ - makeURL : function(relativeURL) { - return DOCUMENTATION_OPTIONS.URL_ROOT + '/' + relativeURL; - }, - - /** - * get the current relative url - */ - getCurrentURL : function() { - var path = document.location.pathname; - var parts = path.split(/\//); - $.each(DOCUMENTATION_OPTIONS.URL_ROOT.split(/\//), function() { - if (this == '..') - parts.pop(); - }); - var url = parts.join('/'); - return path.substring(url.lastIndexOf('/') + 1, path.length - 1); - } -}; - -// quick alias for translations -_ = Documentation.gettext; - -$(document).ready(function() { - Documentation.init(); -}); diff --git a/docs/_build/html/_static/down-pressed.png b/docs/_build/html/_static/down-pressed.png deleted file mode 100644 index 6f7ad782..00000000 Binary files a/docs/_build/html/_static/down-pressed.png and /dev/null differ diff --git a/docs/_build/html/_static/down.png b/docs/_build/html/_static/down.png deleted file mode 100644 index 3003a887..00000000 Binary files a/docs/_build/html/_static/down.png and /dev/null differ diff --git a/docs/_build/html/_static/file.png b/docs/_build/html/_static/file.png deleted file mode 100644 index d18082e3..00000000 Binary files a/docs/_build/html/_static/file.png and /dev/null differ diff --git a/docs/_build/html/_static/jquery.js b/docs/_build/html/_static/jquery.js deleted file mode 100644 index e2efc335..00000000 --- a/docs/_build/html/_static/jquery.js +++ /dev/null @@ -1,9404 +0,0 @@ -/*! - * jQuery JavaScript Library v1.7.2 - * http://jquery.com/ - * - * Copyright 2011, John Resig - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * Includes Sizzle.js - * http://sizzlejs.com/ - * Copyright 2011, The Dojo Foundation - * Released under the MIT, BSD, and GPL Licenses. - * - * Date: Fri Jul 5 14:07:58 UTC 2013 - */ -(function( window, undefined ) { - -// Use the correct document accordingly with window argument (sandbox) -var document = window.document, - navigator = window.navigator, - location = window.location; -var jQuery = (function() { - -// Define a local copy of jQuery -var jQuery = function( selector, context ) { - // The jQuery object is actually just the init constructor 'enhanced' - return new jQuery.fn.init( selector, context, rootjQuery ); - }, - - // Map over jQuery in case of overwrite - _jQuery = window.jQuery, - - // Map over the $ in case of overwrite - _$ = window.$, - - // A central reference to the root jQuery(document) - rootjQuery, - - // A simple way to check for HTML strings or ID strings - // Prioritize #id over to avoid XSS via location.hash (#9521) - quickExpr = /^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/, - - // Check if a string has a non-whitespace character in it - rnotwhite = /\S/, - - // Used for trimming whitespace - trimLeft = /^\s+/, - trimRight = /\s+$/, - - // Match a standalone tag - rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>)?$/, - - // JSON RegExp - rvalidchars = /^[\],:{}\s]*$/, - rvalidescape = /\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, - rvalidtokens = /"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, - rvalidbraces = /(?:^|:|,)(?:\s*\[)+/g, - - // Useragent RegExp - rwebkit = /(webkit)[ \/]([\w.]+)/, - ropera = /(opera)(?:.*version)?[ \/]([\w.]+)/, - rmsie = /(msie) ([\w.]+)/, - rmozilla = /(mozilla)(?:.*? rv:([\w.]+))?/, - - // Matches dashed string for camelizing - rdashAlpha = /-([a-z]|[0-9])/ig, - rmsPrefix = /^-ms-/, - - // Used by jQuery.camelCase as callback to replace() - fcamelCase = function( all, letter ) { - return ( letter + "" ).toUpperCase(); - }, - - // Keep a UserAgent string for use with jQuery.browser - userAgent = navigator.userAgent, - - // For matching the engine and version of the browser - browserMatch, - - // The deferred used on DOM ready - readyList, - - // The ready event handler - DOMContentLoaded, - - // Save a reference to some core methods - toString = Object.prototype.toString, - hasOwn = Object.prototype.hasOwnProperty, - push = Array.prototype.push, - slice = Array.prototype.slice, - trim = String.prototype.trim, - indexOf = Array.prototype.indexOf, - - // [[Class]] -> type pairs - class2type = {}; - -jQuery.fn = jQuery.prototype = { - constructor: jQuery, - init: function( selector, context, rootjQuery ) { - var match, elem, ret, doc; - - // Handle $(""), $(null), or $(undefined) - if ( !selector ) { - return this; - } - - // Handle $(DOMElement) - if ( selector.nodeType ) { - this.context = this[0] = selector; - this.length = 1; - return this; - } - - // The body element only exists once, optimize finding it - if ( selector === "body" && !context && document.body ) { - this.context = document; - this[0] = document.body; - this.selector = selector; - this.length = 1; - return this; - } - - // Handle HTML strings - if ( typeof selector === "string" ) { - // Are we dealing with HTML string or an ID? - if ( selector.charAt(0) === "<" && selector.charAt( selector.length - 1 ) === ">" && selector.length >= 3 ) { - // Assume that strings that start and end with <> are HTML and skip the regex check - match = [ null, selector, null ]; - - } else { - match = quickExpr.exec( selector ); - } - - // Verify a match, and that no context was specified for #id - if ( match && (match[1] || !context) ) { - - // HANDLE: $(html) -> $(array) - if ( match[1] ) { - context = context instanceof jQuery ? context[0] : context; - doc = ( context ? context.ownerDocument || context : document ); - - // If a single string is passed in and it's a single tag - // just do a createElement and skip the rest - ret = rsingleTag.exec( selector ); - - if ( ret ) { - if ( jQuery.isPlainObject( context ) ) { - selector = [ document.createElement( ret[1] ) ]; - jQuery.fn.attr.call( selector, context, true ); - - } else { - selector = [ doc.createElement( ret[1] ) ]; - } - - } else { - ret = jQuery.buildFragment( [ match[1] ], [ doc ] ); - selector = ( ret.cacheable ? jQuery.clone(ret.fragment) : ret.fragment ).childNodes; - } - - return jQuery.merge( this, selector ); - - // HANDLE: $("#id") - } else { - elem = document.getElementById( match[2] ); - - // Check parentNode to catch when Blackberry 4.6 returns - // nodes that are no longer in the document #6963 - if ( elem && elem.parentNode ) { - // Handle the case where IE and Opera return items - // by name instead of ID - if ( elem.id !== match[2] ) { - return rootjQuery.find( selector ); - } - - // Otherwise, we inject the element directly into the jQuery object - this.length = 1; - this[0] = elem; - } - - this.context = document; - this.selector = selector; - return this; - } - - // HANDLE: $(expr, $(...)) - } else if ( !context || context.jquery ) { - return ( context || rootjQuery ).find( selector ); - - // HANDLE: $(expr, context) - // (which is just equivalent to: $(context).find(expr) - } else { - return this.constructor( context ).find( selector ); - } - - // HANDLE: $(function) - // Shortcut for document ready - } else if ( jQuery.isFunction( selector ) ) { - return rootjQuery.ready( selector ); - } - - if ( selector.selector !== undefined ) { - this.selector = selector.selector; - this.context = selector.context; - } - - return jQuery.makeArray( selector, this ); - }, - - // Start with an empty selector - selector: "", - - // The current version of jQuery being used - jquery: "1.7.2", - - // The default length of a jQuery object is 0 - length: 0, - - // The number of elements contained in the matched element set - size: function() { - return this.length; - }, - - toArray: function() { - return slice.call( this, 0 ); - }, - - // Get the Nth element in the matched element set OR - // Get the whole matched element set as a clean array - get: function( num ) { - return num == null ? - - // Return a 'clean' array - this.toArray() : - - // Return just the object - ( num < 0 ? this[ this.length + num ] : this[ num ] ); - }, - - // Take an array of elements and push it onto the stack - // (returning the new matched element set) - pushStack: function( elems, name, selector ) { - // Build a new jQuery matched element set - var ret = this.constructor(); - - if ( jQuery.isArray( elems ) ) { - push.apply( ret, elems ); - - } else { - jQuery.merge( ret, elems ); - } - - // Add the old object onto the stack (as a reference) - ret.prevObject = this; - - ret.context = this.context; - - if ( name === "find" ) { - ret.selector = this.selector + ( this.selector ? " " : "" ) + selector; - } else if ( name ) { - ret.selector = this.selector + "." + name + "(" + selector + ")"; - } - - // Return the newly-formed element set - return ret; - }, - - // Execute a callback for every element in the matched set. - // (You can seed the arguments with an array of args, but this is - // only used internally.) - each: function( callback, args ) { - return jQuery.each( this, callback, args ); - }, - - ready: function( fn ) { - // Attach the listeners - jQuery.bindReady(); - - // Add the callback - readyList.add( fn ); - - return this; - }, - - eq: function( i ) { - i = +i; - return i === -1 ? - this.slice( i ) : - this.slice( i, i + 1 ); - }, - - first: function() { - return this.eq( 0 ); - }, - - last: function() { - return this.eq( -1 ); - }, - - slice: function() { - return this.pushStack( slice.apply( this, arguments ), - "slice", slice.call(arguments).join(",") ); - }, - - map: function( callback ) { - return this.pushStack( jQuery.map(this, function( elem, i ) { - return callback.call( elem, i, elem ); - })); - }, - - end: function() { - return this.prevObject || this.constructor(null); - }, - - // For internal use only. - // Behaves like an Array's method, not like a jQuery method. - push: push, - sort: [].sort, - splice: [].splice -}; - -// Give the init function the jQuery prototype for later instantiation -jQuery.fn.init.prototype = jQuery.fn; - -jQuery.extend = jQuery.fn.extend = function() { - var options, name, src, copy, copyIsArray, clone, - target = arguments[0] || {}, - i = 1, - length = arguments.length, - deep = false; - - // Handle a deep copy situation - if ( typeof target === "boolean" ) { - deep = target; - target = arguments[1] || {}; - // skip the boolean and the target - i = 2; - } - - // Handle case when target is a string or something (possible in deep copy) - if ( typeof target !== "object" && !jQuery.isFunction(target) ) { - target = {}; - } - - // extend jQuery itself if only one argument is passed - if ( length === i ) { - target = this; - --i; - } - - for ( ; i < length; i++ ) { - // Only deal with non-null/undefined values - if ( (options = arguments[ i ]) != null ) { - // Extend the base object - for ( name in options ) { - src = target[ name ]; - copy = options[ name ]; - - // Prevent never-ending loop - if ( target === copy ) { - continue; - } - - // Recurse if we're merging plain objects or arrays - if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) { - if ( copyIsArray ) { - copyIsArray = false; - clone = src && jQuery.isArray(src) ? src : []; - - } else { - clone = src && jQuery.isPlainObject(src) ? src : {}; - } - - // Never move original objects, clone them - target[ name ] = jQuery.extend( deep, clone, copy ); - - // Don't bring in undefined values - } else if ( copy !== undefined ) { - target[ name ] = copy; - } - } - } - } - - // Return the modified object - return target; -}; - -jQuery.extend({ - noConflict: function( deep ) { - if ( window.$ === jQuery ) { - window.$ = _$; - } - - if ( deep && window.jQuery === jQuery ) { - window.jQuery = _jQuery; - } - - return jQuery; - }, - - // Is the DOM ready to be used? Set to true once it occurs. - isReady: false, - - // A counter to track how many items to wait for before - // the ready event fires. See #6781 - readyWait: 1, - - // Hold (or release) the ready event - holdReady: function( hold ) { - if ( hold ) { - jQuery.readyWait++; - } else { - jQuery.ready( true ); - } - }, - - // Handle when the DOM is ready - ready: function( wait ) { - // Either a released hold or an DOMready/load event and not yet ready - if ( (wait === true && !--jQuery.readyWait) || (wait !== true && !jQuery.isReady) ) { - // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443). - if ( !document.body ) { - return setTimeout( jQuery.ready, 1 ); - } - - // Remember that the DOM is ready - jQuery.isReady = true; - - // If a normal DOM Ready event fired, decrement, and wait if need be - if ( wait !== true && --jQuery.readyWait > 0 ) { - return; - } - - // If there are functions bound, to execute - readyList.fireWith( document, [ jQuery ] ); - - // Trigger any bound ready events - if ( jQuery.fn.trigger ) { - jQuery( document ).trigger( "ready" ).off( "ready" ); - } - } - }, - - bindReady: function() { - if ( readyList ) { - return; - } - - readyList = jQuery.Callbacks( "once memory" ); - - // Catch cases where $(document).ready() is called after the - // browser event has already occurred. - if ( document.readyState === "complete" ) { - // Handle it asynchronously to allow scripts the opportunity to delay ready - return setTimeout( jQuery.ready, 1 ); - } - - // Mozilla, Opera and webkit nightlies currently support this event - if ( document.addEventListener ) { - // Use the handy event callback - document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false ); - - // A fallback to window.onload, that will always work - window.addEventListener( "load", jQuery.ready, false ); - - // If IE event model is used - } else if ( document.attachEvent ) { - // ensure firing before onload, - // maybe late but safe also for iframes - document.attachEvent( "onreadystatechange", DOMContentLoaded ); - - // A fallback to window.onload, that will always work - window.attachEvent( "onload", jQuery.ready ); - - // If IE and not a frame - // continually check to see if the document is ready - var toplevel = false; - - try { - toplevel = window.frameElement == null; - } catch(e) {} - - if ( document.documentElement.doScroll && toplevel ) { - doScrollCheck(); - } - } - }, - - // See test/unit/core.js for details concerning isFunction. - // Since version 1.3, DOM methods and functions like alert - // aren't supported. They return false on IE (#2968). - isFunction: function( obj ) { - return jQuery.type(obj) === "function"; - }, - - isArray: Array.isArray || function( obj ) { - return jQuery.type(obj) === "array"; - }, - - isWindow: function( obj ) { - return obj != null && obj == obj.window; - }, - - isNumeric: function( obj ) { - return !isNaN( parseFloat(obj) ) && isFinite( obj ); - }, - - type: function( obj ) { - return obj == null ? - String( obj ) : - class2type[ toString.call(obj) ] || "object"; - }, - - isPlainObject: function( obj ) { - // Must be an Object. - // Because of IE, we also have to check the presence of the constructor property. - // Make sure that DOM nodes and window objects don't pass through, as well - if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) { - return false; - } - - try { - // Not own constructor property must be Object - if ( obj.constructor && - !hasOwn.call(obj, "constructor") && - !hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) { - return false; - } - } catch ( e ) { - // IE8,9 Will throw exceptions on certain host objects #9897 - return false; - } - - // Own properties are enumerated firstly, so to speed up, - // if last one is own, then all properties are own. - - var key; - for ( key in obj ) {} - - return key === undefined || hasOwn.call( obj, key ); - }, - - isEmptyObject: function( obj ) { - for ( var name in obj ) { - return false; - } - return true; - }, - - error: function( msg ) { - throw new Error( msg ); - }, - - parseJSON: function( data ) { - if ( typeof data !== "string" || !data ) { - return null; - } - - // Make sure leading/trailing whitespace is removed (IE can't handle it) - data = jQuery.trim( data ); - - // Attempt to parse using the native JSON parser first - if ( window.JSON && window.JSON.parse ) { - return window.JSON.parse( data ); - } - - // Make sure the incoming data is actual JSON - // Logic borrowed from http://json.org/json2.js - if ( rvalidchars.test( data.replace( rvalidescape, "@" ) - .replace( rvalidtokens, "]" ) - .replace( rvalidbraces, "")) ) { - - return ( new Function( "return " + data ) )(); - - } - jQuery.error( "Invalid JSON: " + data ); - }, - - // Cross-browser xml parsing - parseXML: function( data ) { - if ( typeof data !== "string" || !data ) { - return null; - } - var xml, tmp; - try { - if ( window.DOMParser ) { // Standard - tmp = new DOMParser(); - xml = tmp.parseFromString( data , "text/xml" ); - } else { // IE - xml = new ActiveXObject( "Microsoft.XMLDOM" ); - xml.async = "false"; - xml.loadXML( data ); - } - } catch( e ) { - xml = undefined; - } - if ( !xml || !xml.documentElement || xml.getElementsByTagName( "parsererror" ).length ) { - jQuery.error( "Invalid XML: " + data ); - } - return xml; - }, - - noop: function() {}, - - // Evaluates a script in a global context - // Workarounds based on findings by Jim Driscoll - // http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context - globalEval: function( data ) { - if ( data && rnotwhite.test( data ) ) { - // We use execScript on Internet Explorer - // We use an anonymous function so that context is window - // rather than jQuery in Firefox - ( window.execScript || function( data ) { - window[ "eval" ].call( window, data ); - } )( data ); - } - }, - - // Convert dashed to camelCase; used by the css and data modules - // Microsoft forgot to hump their vendor prefix (#9572) - camelCase: function( string ) { - return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase ); - }, - - nodeName: function( elem, name ) { - return elem.nodeName && elem.nodeName.toUpperCase() === name.toUpperCase(); - }, - - // args is for internal usage only - each: function( object, callback, args ) { - var name, i = 0, - length = object.length, - isObj = length === undefined || jQuery.isFunction( object ); - - if ( args ) { - if ( isObj ) { - for ( name in object ) { - if ( callback.apply( object[ name ], args ) === false ) { - break; - } - } - } else { - for ( ; i < length; ) { - if ( callback.apply( object[ i++ ], args ) === false ) { - break; - } - } - } - - // A special, fast, case for the most common use of each - } else { - if ( isObj ) { - for ( name in object ) { - if ( callback.call( object[ name ], name, object[ name ] ) === false ) { - break; - } - } - } else { - for ( ; i < length; ) { - if ( callback.call( object[ i ], i, object[ i++ ] ) === false ) { - break; - } - } - } - } - - return object; - }, - - // Use native String.trim function wherever possible - trim: trim ? - function( text ) { - return text == null ? - "" : - trim.call( text ); - } : - - // Otherwise use our own trimming functionality - function( text ) { - return text == null ? - "" : - text.toString().replace( trimLeft, "" ).replace( trimRight, "" ); - }, - - // results is for internal usage only - makeArray: function( array, results ) { - var ret = results || []; - - if ( array != null ) { - // The window, strings (and functions) also have 'length' - // Tweaked logic slightly to handle Blackberry 4.7 RegExp issues #6930 - var type = jQuery.type( array ); - - if ( array.length == null || type === "string" || type === "function" || type === "regexp" || jQuery.isWindow( array ) ) { - push.call( ret, array ); - } else { - jQuery.merge( ret, array ); - } - } - - return ret; - }, - - inArray: function( elem, array, i ) { - var len; - - if ( array ) { - if ( indexOf ) { - return indexOf.call( array, elem, i ); - } - - len = array.length; - i = i ? i < 0 ? Math.max( 0, len + i ) : i : 0; - - for ( ; i < len; i++ ) { - // Skip accessing in sparse arrays - if ( i in array && array[ i ] === elem ) { - return i; - } - } - } - - return -1; - }, - - merge: function( first, second ) { - var i = first.length, - j = 0; - - if ( typeof second.length === "number" ) { - for ( var l = second.length; j < l; j++ ) { - first[ i++ ] = second[ j ]; - } - - } else { - while ( second[j] !== undefined ) { - first[ i++ ] = second[ j++ ]; - } - } - - first.length = i; - - return first; - }, - - grep: function( elems, callback, inv ) { - var ret = [], retVal; - inv = !!inv; - - // Go through the array, only saving the items - // that pass the validator function - for ( var i = 0, length = elems.length; i < length; i++ ) { - retVal = !!callback( elems[ i ], i ); - if ( inv !== retVal ) { - ret.push( elems[ i ] ); - } - } - - return ret; - }, - - // arg is for internal usage only - map: function( elems, callback, arg ) { - var value, key, ret = [], - i = 0, - length = elems.length, - // jquery objects are treated as arrays - isArray = elems instanceof jQuery || length !== undefined && typeof length === "number" && ( ( length > 0 && elems[ 0 ] && elems[ length -1 ] ) || length === 0 || jQuery.isArray( elems ) ) ; - - // Go through the array, translating each of the items to their - if ( isArray ) { - for ( ; i < length; i++ ) { - value = callback( elems[ i ], i, arg ); - - if ( value != null ) { - ret[ ret.length ] = value; - } - } - - // Go through every key on the object, - } else { - for ( key in elems ) { - value = callback( elems[ key ], key, arg ); - - if ( value != null ) { - ret[ ret.length ] = value; - } - } - } - - // Flatten any nested arrays - return ret.concat.apply( [], ret ); - }, - - // A global GUID counter for objects - guid: 1, - - // Bind a function to a context, optionally partially applying any - // arguments. - proxy: function( fn, context ) { - if ( typeof context === "string" ) { - var tmp = fn[ context ]; - context = fn; - fn = tmp; - } - - // Quick check to determine if target is callable, in the spec - // this throws a TypeError, but we will just return undefined. - if ( !jQuery.isFunction( fn ) ) { - return undefined; - } - - // Simulated bind - var args = slice.call( arguments, 2 ), - proxy = function() { - return fn.apply( context, args.concat( slice.call( arguments ) ) ); - }; - - // Set the guid of unique handler to the same of original handler, so it can be removed - proxy.guid = fn.guid = fn.guid || proxy.guid || jQuery.guid++; - - return proxy; - }, - - // Mutifunctional method to get and set values to a collection - // The value/s can optionally be executed if it's a function - access: function( elems, fn, key, value, chainable, emptyGet, pass ) { - var exec, - bulk = key == null, - i = 0, - length = elems.length; - - // Sets many values - if ( key && typeof key === "object" ) { - for ( i in key ) { - jQuery.access( elems, fn, i, key[i], 1, emptyGet, value ); - } - chainable = 1; - - // Sets one value - } else if ( value !== undefined ) { - // Optionally, function values get executed if exec is true - exec = pass === undefined && jQuery.isFunction( value ); - - if ( bulk ) { - // Bulk operations only iterate when executing function values - if ( exec ) { - exec = fn; - fn = function( elem, key, value ) { - return exec.call( jQuery( elem ), value ); - }; - - // Otherwise they run against the entire set - } else { - fn.call( elems, value ); - fn = null; - } - } - - if ( fn ) { - for (; i < length; i++ ) { - fn( elems[i], key, exec ? value.call( elems[i], i, fn( elems[i], key ) ) : value, pass ); - } - } - - chainable = 1; - } - - return chainable ? - elems : - - // Gets - bulk ? - fn.call( elems ) : - length ? fn( elems[0], key ) : emptyGet; - }, - - now: function() { - return ( new Date() ).getTime(); - }, - - // Use of jQuery.browser is frowned upon. - // More details: http://docs.jquery.com/Utilities/jQuery.browser - uaMatch: function( ua ) { - ua = ua.toLowerCase(); - - var match = rwebkit.exec( ua ) || - ropera.exec( ua ) || - rmsie.exec( ua ) || - ua.indexOf("compatible") < 0 && rmozilla.exec( ua ) || - []; - - return { browser: match[1] || "", version: match[2] || "0" }; - }, - - sub: function() { - function jQuerySub( selector, context ) { - return new jQuerySub.fn.init( selector, context ); - } - jQuery.extend( true, jQuerySub, this ); - jQuerySub.superclass = this; - jQuerySub.fn = jQuerySub.prototype = this(); - jQuerySub.fn.constructor = jQuerySub; - jQuerySub.sub = this.sub; - jQuerySub.fn.init = function init( selector, context ) { - if ( context && context instanceof jQuery && !(context instanceof jQuerySub) ) { - context = jQuerySub( context ); - } - - return jQuery.fn.init.call( this, selector, context, rootjQuerySub ); - }; - jQuerySub.fn.init.prototype = jQuerySub.fn; - var rootjQuerySub = jQuerySub(document); - return jQuerySub; - }, - - browser: {} -}); - -// Populate the class2type map -jQuery.each("Boolean Number String Function Array Date RegExp Object".split(" "), function(i, name) { - class2type[ "[object " + name + "]" ] = name.toLowerCase(); -}); - -browserMatch = jQuery.uaMatch( userAgent ); -if ( browserMatch.browser ) { - jQuery.browser[ browserMatch.browser ] = true; - jQuery.browser.version = browserMatch.version; -} - -// Deprecated, use jQuery.browser.webkit instead -if ( jQuery.browser.webkit ) { - jQuery.browser.safari = true; -} - -// IE doesn't match non-breaking spaces with \s -if ( rnotwhite.test( "\xA0" ) ) { - trimLeft = /^[\s\xA0]+/; - trimRight = /[\s\xA0]+$/; -} - -// All jQuery objects should point back to these -rootjQuery = jQuery(document); - -// Cleanup functions for the document ready method -if ( document.addEventListener ) { - DOMContentLoaded = function() { - document.removeEventListener( "DOMContentLoaded", DOMContentLoaded, false ); - jQuery.ready(); - }; - -} else if ( document.attachEvent ) { - DOMContentLoaded = function() { - // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443). - if ( document.readyState === "complete" ) { - document.detachEvent( "onreadystatechange", DOMContentLoaded ); - jQuery.ready(); - } - }; -} - -// The DOM ready check for Internet Explorer -function doScrollCheck() { - if ( jQuery.isReady ) { - return; - } - - try { - // If IE is used, use the trick by Diego Perini - // http://javascript.nwbox.com/IEContentLoaded/ - document.documentElement.doScroll("left"); - } catch(e) { - setTimeout( doScrollCheck, 1 ); - return; - } - - // and execute any waiting functions - jQuery.ready(); -} - -return jQuery; - -})(); - - -// String to Object flags format cache -var flagsCache = {}; - -// Convert String-formatted flags into Object-formatted ones and store in cache -function createFlags( flags ) { - var object = flagsCache[ flags ] = {}, - i, length; - flags = flags.split( /\s+/ ); - for ( i = 0, length = flags.length; i < length; i++ ) { - object[ flags[i] ] = true; - } - return object; -} - -/* - * Create a callback list using the following parameters: - * - * flags: an optional list of space-separated flags that will change how - * the callback list behaves - * - * By default a callback list will act like an event callback list and can be - * "fired" multiple times. - * - * Possible flags: - * - * once: will ensure the callback list can only be fired once (like a Deferred) - * - * memory: will keep track of previous values and will call any callback added - * after the list has been fired right away with the latest "memorized" - * values (like a Deferred) - * - * unique: will ensure a callback can only be added once (no duplicate in the list) - * - * stopOnFalse: interrupt callings when a callback returns false - * - */ -jQuery.Callbacks = function( flags ) { - - // Convert flags from String-formatted to Object-formatted - // (we check in cache first) - flags = flags ? ( flagsCache[ flags ] || createFlags( flags ) ) : {}; - - var // Actual callback list - list = [], - // Stack of fire calls for repeatable lists - stack = [], - // Last fire value (for non-forgettable lists) - memory, - // Flag to know if list was already fired - fired, - // Flag to know if list is currently firing - firing, - // First callback to fire (used internally by add and fireWith) - firingStart, - // End of the loop when firing - firingLength, - // Index of currently firing callback (modified by remove if needed) - firingIndex, - // Add one or several callbacks to the list - add = function( args ) { - var i, - length, - elem, - type, - actual; - for ( i = 0, length = args.length; i < length; i++ ) { - elem = args[ i ]; - type = jQuery.type( elem ); - if ( type === "array" ) { - // Inspect recursively - add( elem ); - } else if ( type === "function" ) { - // Add if not in unique mode and callback is not in - if ( !flags.unique || !self.has( elem ) ) { - list.push( elem ); - } - } - } - }, - // Fire callbacks - fire = function( context, args ) { - args = args || []; - memory = !flags.memory || [ context, args ]; - fired = true; - firing = true; - firingIndex = firingStart || 0; - firingStart = 0; - firingLength = list.length; - for ( ; list && firingIndex < firingLength; firingIndex++ ) { - if ( list[ firingIndex ].apply( context, args ) === false && flags.stopOnFalse ) { - memory = true; // Mark as halted - break; - } - } - firing = false; - if ( list ) { - if ( !flags.once ) { - if ( stack && stack.length ) { - memory = stack.shift(); - self.fireWith( memory[ 0 ], memory[ 1 ] ); - } - } else if ( memory === true ) { - self.disable(); - } else { - list = []; - } - } - }, - // Actual Callbacks object - self = { - // Add a callback or a collection of callbacks to the list - add: function() { - if ( list ) { - var length = list.length; - add( arguments ); - // Do we need to add the callbacks to the - // current firing batch? - if ( firing ) { - firingLength = list.length; - // With memory, if we're not firing then - // we should call right away, unless previous - // firing was halted (stopOnFalse) - } else if ( memory && memory !== true ) { - firingStart = length; - fire( memory[ 0 ], memory[ 1 ] ); - } - } - return this; - }, - // Remove a callback from the list - remove: function() { - if ( list ) { - var args = arguments, - argIndex = 0, - argLength = args.length; - for ( ; argIndex < argLength ; argIndex++ ) { - for ( var i = 0; i < list.length; i++ ) { - if ( args[ argIndex ] === list[ i ] ) { - // Handle firingIndex and firingLength - if ( firing ) { - if ( i <= firingLength ) { - firingLength--; - if ( i <= firingIndex ) { - firingIndex--; - } - } - } - // Remove the element - list.splice( i--, 1 ); - // If we have some unicity property then - // we only need to do this once - if ( flags.unique ) { - break; - } - } - } - } - } - return this; - }, - // Control if a given callback is in the list - has: function( fn ) { - if ( list ) { - var i = 0, - length = list.length; - for ( ; i < length; i++ ) { - if ( fn === list[ i ] ) { - return true; - } - } - } - return false; - }, - // Remove all callbacks from the list - empty: function() { - list = []; - return this; - }, - // Have the list do nothing anymore - disable: function() { - list = stack = memory = undefined; - return this; - }, - // Is it disabled? - disabled: function() { - return !list; - }, - // Lock the list in its current state - lock: function() { - stack = undefined; - if ( !memory || memory === true ) { - self.disable(); - } - return this; - }, - // Is it locked? - locked: function() { - return !stack; - }, - // Call all callbacks with the given context and arguments - fireWith: function( context, args ) { - if ( stack ) { - if ( firing ) { - if ( !flags.once ) { - stack.push( [ context, args ] ); - } - } else if ( !( flags.once && memory ) ) { - fire( context, args ); - } - } - return this; - }, - // Call all the callbacks with the given arguments - fire: function() { - self.fireWith( this, arguments ); - return this; - }, - // To know if the callbacks have already been called at least once - fired: function() { - return !!fired; - } - }; - - return self; -}; - - - - -var // Static reference to slice - sliceDeferred = [].slice; - -jQuery.extend({ - - Deferred: function( func ) { - var doneList = jQuery.Callbacks( "once memory" ), - failList = jQuery.Callbacks( "once memory" ), - progressList = jQuery.Callbacks( "memory" ), - state = "pending", - lists = { - resolve: doneList, - reject: failList, - notify: progressList - }, - promise = { - done: doneList.add, - fail: failList.add, - progress: progressList.add, - - state: function() { - return state; - }, - - // Deprecated - isResolved: doneList.fired, - isRejected: failList.fired, - - then: function( doneCallbacks, failCallbacks, progressCallbacks ) { - deferred.done( doneCallbacks ).fail( failCallbacks ).progress( progressCallbacks ); - return this; - }, - always: function() { - deferred.done.apply( deferred, arguments ).fail.apply( deferred, arguments ); - return this; - }, - pipe: function( fnDone, fnFail, fnProgress ) { - return jQuery.Deferred(function( newDefer ) { - jQuery.each( { - done: [ fnDone, "resolve" ], - fail: [ fnFail, "reject" ], - progress: [ fnProgress, "notify" ] - }, function( handler, data ) { - var fn = data[ 0 ], - action = data[ 1 ], - returned; - if ( jQuery.isFunction( fn ) ) { - deferred[ handler ](function() { - returned = fn.apply( this, arguments ); - if ( returned && jQuery.isFunction( returned.promise ) ) { - returned.promise().then( newDefer.resolve, newDefer.reject, newDefer.notify ); - } else { - newDefer[ action + "With" ]( this === deferred ? newDefer : this, [ returned ] ); - } - }); - } else { - deferred[ handler ]( newDefer[ action ] ); - } - }); - }).promise(); - }, - // Get a promise for this deferred - // If obj is provided, the promise aspect is added to the object - promise: function( obj ) { - if ( obj == null ) { - obj = promise; - } else { - for ( var key in promise ) { - obj[ key ] = promise[ key ]; - } - } - return obj; - } - }, - deferred = promise.promise({}), - key; - - for ( key in lists ) { - deferred[ key ] = lists[ key ].fire; - deferred[ key + "With" ] = lists[ key ].fireWith; - } - - // Handle state - deferred.done( function() { - state = "resolved"; - }, failList.disable, progressList.lock ).fail( function() { - state = "rejected"; - }, doneList.disable, progressList.lock ); - - // Call given func if any - if ( func ) { - func.call( deferred, deferred ); - } - - // All done! - return deferred; - }, - - // Deferred helper - when: function( firstParam ) { - var args = sliceDeferred.call( arguments, 0 ), - i = 0, - length = args.length, - pValues = new Array( length ), - count = length, - pCount = length, - deferred = length <= 1 && firstParam && jQuery.isFunction( firstParam.promise ) ? - firstParam : - jQuery.Deferred(), - promise = deferred.promise(); - function resolveFunc( i ) { - return function( value ) { - args[ i ] = arguments.length > 1 ? sliceDeferred.call( arguments, 0 ) : value; - if ( !( --count ) ) { - deferred.resolveWith( deferred, args ); - } - }; - } - function progressFunc( i ) { - return function( value ) { - pValues[ i ] = arguments.length > 1 ? sliceDeferred.call( arguments, 0 ) : value; - deferred.notifyWith( promise, pValues ); - }; - } - if ( length > 1 ) { - for ( ; i < length; i++ ) { - if ( args[ i ] && args[ i ].promise && jQuery.isFunction( args[ i ].promise ) ) { - args[ i ].promise().then( resolveFunc(i), deferred.reject, progressFunc(i) ); - } else { - --count; - } - } - if ( !count ) { - deferred.resolveWith( deferred, args ); - } - } else if ( deferred !== firstParam ) { - deferred.resolveWith( deferred, length ? [ firstParam ] : [] ); - } - return promise; - } -}); - - - - -jQuery.support = (function() { - - var support, - all, - a, - select, - opt, - input, - fragment, - tds, - events, - eventName, - i, - isSupported, - div = document.createElement( "div" ), - documentElement = document.documentElement; - - // Preliminary tests - div.setAttribute("className", "t"); - div.innerHTML = "
a"; - - all = div.getElementsByTagName( "*" ); - a = div.getElementsByTagName( "a" )[ 0 ]; - - // Can't get basic test support - if ( !all || !all.length || !a ) { - return {}; - } - - // First batch of supports tests - select = document.createElement( "select" ); - opt = select.appendChild( document.createElement("option") ); - input = div.getElementsByTagName( "input" )[ 0 ]; - - support = { - // IE strips leading whitespace when .innerHTML is used - leadingWhitespace: ( div.firstChild.nodeType === 3 ), - - // Make sure that tbody elements aren't automatically inserted - // IE will insert them into empty tables - tbody: !div.getElementsByTagName("tbody").length, - - // Make sure that link elements get serialized correctly by innerHTML - // This requires a wrapper element in IE - htmlSerialize: !!div.getElementsByTagName("link").length, - - // Get the style information from getAttribute - // (IE uses .cssText instead) - style: /top/.test( a.getAttribute("style") ), - - // Make sure that URLs aren't manipulated - // (IE normalizes it by default) - hrefNormalized: ( a.getAttribute("href") === "/a" ), - - // Make sure that element opacity exists - // (IE uses filter instead) - // Use a regex to work around a WebKit issue. See #5145 - opacity: /^0.55/.test( a.style.opacity ), - - // Verify style float existence - // (IE uses styleFloat instead of cssFloat) - cssFloat: !!a.style.cssFloat, - - // Make sure that if no value is specified for a checkbox - // that it defaults to "on". - // (WebKit defaults to "" instead) - checkOn: ( input.value === "on" ), - - // Make sure that a selected-by-default option has a working selected property. - // (WebKit defaults to false instead of true, IE too, if it's in an optgroup) - optSelected: opt.selected, - - // Test setAttribute on camelCase class. If it works, we need attrFixes when doing get/setAttribute (ie6/7) - getSetAttribute: div.className !== "t", - - // Tests for enctype support on a form(#6743) - enctype: !!document.createElement("form").enctype, - - // Makes sure cloning an html5 element does not cause problems - // Where outerHTML is undefined, this still works - html5Clone: document.createElement("nav").cloneNode( true ).outerHTML !== "<:nav>", - - // Will be defined later - submitBubbles: true, - changeBubbles: true, - focusinBubbles: false, - deleteExpando: true, - noCloneEvent: true, - inlineBlockNeedsLayout: false, - shrinkWrapBlocks: false, - reliableMarginRight: true, - pixelMargin: true - }; - - // jQuery.boxModel DEPRECATED in 1.3, use jQuery.support.boxModel instead - jQuery.boxModel = support.boxModel = (document.compatMode === "CSS1Compat"); - - // Make sure checked status is properly cloned - input.checked = true; - support.noCloneChecked = input.cloneNode( true ).checked; - - // Make sure that the options inside disabled selects aren't marked as disabled - // (WebKit marks them as disabled) - select.disabled = true; - support.optDisabled = !opt.disabled; - - // Test to see if it's possible to delete an expando from an element - // Fails in Internet Explorer - try { - delete div.test; - } catch( e ) { - support.deleteExpando = false; - } - - if ( !div.addEventListener && div.attachEvent && div.fireEvent ) { - div.attachEvent( "onclick", function() { - // Cloning a node shouldn't copy over any - // bound event handlers (IE does this) - support.noCloneEvent = false; - }); - div.cloneNode( true ).fireEvent( "onclick" ); - } - - // Check if a radio maintains its value - // after being appended to the DOM - input = document.createElement("input"); - input.value = "t"; - input.setAttribute("type", "radio"); - support.radioValue = input.value === "t"; - - input.setAttribute("checked", "checked"); - - // #11217 - WebKit loses check when the name is after the checked attribute - input.setAttribute( "name", "t" ); - - div.appendChild( input ); - fragment = document.createDocumentFragment(); - fragment.appendChild( div.lastChild ); - - // WebKit doesn't clone checked state correctly in fragments - support.checkClone = fragment.cloneNode( true ).cloneNode( true ).lastChild.checked; - - // Check if a disconnected checkbox will retain its checked - // value of true after appended to the DOM (IE6/7) - support.appendChecked = input.checked; - - fragment.removeChild( input ); - fragment.appendChild( div ); - - // Technique from Juriy Zaytsev - // http://perfectionkills.com/detecting-event-support-without-browser-sniffing/ - // We only care about the case where non-standard event systems - // are used, namely in IE. Short-circuiting here helps us to - // avoid an eval call (in setAttribute) which can cause CSP - // to go haywire. See: https://developer.mozilla.org/en/Security/CSP - if ( div.attachEvent ) { - for ( i in { - submit: 1, - change: 1, - focusin: 1 - }) { - eventName = "on" + i; - isSupported = ( eventName in div ); - if ( !isSupported ) { - div.setAttribute( eventName, "return;" ); - isSupported = ( typeof div[ eventName ] === "function" ); - } - support[ i + "Bubbles" ] = isSupported; - } - } - - fragment.removeChild( div ); - - // Null elements to avoid leaks in IE - fragment = select = opt = div = input = null; - - // Run tests that need a body at doc ready - jQuery(function() { - var container, outer, inner, table, td, offsetSupport, - marginDiv, conMarginTop, style, html, positionTopLeftWidthHeight, - paddingMarginBorderVisibility, paddingMarginBorder, - body = document.getElementsByTagName("body")[0]; - - if ( !body ) { - // Return for frameset docs that don't have a body - return; - } - - conMarginTop = 1; - paddingMarginBorder = "padding:0;margin:0;border:"; - positionTopLeftWidthHeight = "position:absolute;top:0;left:0;width:1px;height:1px;"; - paddingMarginBorderVisibility = paddingMarginBorder + "0;visibility:hidden;"; - style = "style='" + positionTopLeftWidthHeight + paddingMarginBorder + "5px solid #000;"; - html = "
" + - "" + - "
"; - - container = document.createElement("div"); - container.style.cssText = paddingMarginBorderVisibility + "width:0;height:0;position:static;top:0;margin-top:" + conMarginTop + "px"; - body.insertBefore( container, body.firstChild ); - - // Construct the test element - div = document.createElement("div"); - container.appendChild( div ); - - // Check if table cells still have offsetWidth/Height when they are set - // to display:none and there are still other visible table cells in a - // table row; if so, offsetWidth/Height are not reliable for use when - // determining if an element has been hidden directly using - // display:none (it is still safe to use offsets if a parent element is - // hidden; don safety goggles and see bug #4512 for more information). - // (only IE 8 fails this test) - div.innerHTML = "
t
"; - tds = div.getElementsByTagName( "td" ); - isSupported = ( tds[ 0 ].offsetHeight === 0 ); - - tds[ 0 ].style.display = ""; - tds[ 1 ].style.display = "none"; - - // Check if empty table cells still have offsetWidth/Height - // (IE <= 8 fail this test) - support.reliableHiddenOffsets = isSupported && ( tds[ 0 ].offsetHeight === 0 ); - - // Check if div with explicit width and no margin-right incorrectly - // gets computed margin-right based on width of container. For more - // info see bug #3333 - // Fails in WebKit before Feb 2011 nightlies - // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right - if ( window.getComputedStyle ) { - div.innerHTML = ""; - marginDiv = document.createElement( "div" ); - marginDiv.style.width = "0"; - marginDiv.style.marginRight = "0"; - div.style.width = "2px"; - div.appendChild( marginDiv ); - support.reliableMarginRight = - ( parseInt( ( window.getComputedStyle( marginDiv, null ) || { marginRight: 0 } ).marginRight, 10 ) || 0 ) === 0; - } - - if ( typeof div.style.zoom !== "undefined" ) { - // Check if natively block-level elements act like inline-block - // elements when setting their display to 'inline' and giving - // them layout - // (IE < 8 does this) - div.innerHTML = ""; - div.style.width = div.style.padding = "1px"; - div.style.border = 0; - div.style.overflow = "hidden"; - div.style.display = "inline"; - div.style.zoom = 1; - support.inlineBlockNeedsLayout = ( div.offsetWidth === 3 ); - - // Check if elements with layout shrink-wrap their children - // (IE 6 does this) - div.style.display = "block"; - div.style.overflow = "visible"; - div.innerHTML = "
"; - support.shrinkWrapBlocks = ( div.offsetWidth !== 3 ); - } - - div.style.cssText = positionTopLeftWidthHeight + paddingMarginBorderVisibility; - div.innerHTML = html; - - outer = div.firstChild; - inner = outer.firstChild; - td = outer.nextSibling.firstChild.firstChild; - - offsetSupport = { - doesNotAddBorder: ( inner.offsetTop !== 5 ), - doesAddBorderForTableAndCells: ( td.offsetTop === 5 ) - }; - - inner.style.position = "fixed"; - inner.style.top = "20px"; - - // safari subtracts parent border width here which is 5px - offsetSupport.fixedPosition = ( inner.offsetTop === 20 || inner.offsetTop === 15 ); - inner.style.position = inner.style.top = ""; - - outer.style.overflow = "hidden"; - outer.style.position = "relative"; - - offsetSupport.subtractsBorderForOverflowNotVisible = ( inner.offsetTop === -5 ); - offsetSupport.doesNotIncludeMarginInBodyOffset = ( body.offsetTop !== conMarginTop ); - - if ( window.getComputedStyle ) { - div.style.marginTop = "1%"; - support.pixelMargin = ( window.getComputedStyle( div, null ) || { marginTop: 0 } ).marginTop !== "1%"; - } - - if ( typeof container.style.zoom !== "undefined" ) { - container.style.zoom = 1; - } - - body.removeChild( container ); - marginDiv = div = container = null; - - jQuery.extend( support, offsetSupport ); - }); - - return support; -})(); - - - - -var rbrace = /^(?:\{.*\}|\[.*\])$/, - rmultiDash = /([A-Z])/g; - -jQuery.extend({ - cache: {}, - - // Please use with caution - uuid: 0, - - // Unique for each copy of jQuery on the page - // Non-digits removed to match rinlinejQuery - expando: "jQuery" + ( jQuery.fn.jquery + Math.random() ).replace( /\D/g, "" ), - - // The following elements throw uncatchable exceptions if you - // attempt to add expando properties to them. - noData: { - "embed": true, - // Ban all objects except for Flash (which handle expandos) - "object": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000", - "applet": true - }, - - hasData: function( elem ) { - elem = elem.nodeType ? jQuery.cache[ elem[jQuery.expando] ] : elem[ jQuery.expando ]; - return !!elem && !isEmptyDataObject( elem ); - }, - - data: function( elem, name, data, pvt /* Internal Use Only */ ) { - if ( !jQuery.acceptData( elem ) ) { - return; - } - - var privateCache, thisCache, ret, - internalKey = jQuery.expando, - getByName = typeof name === "string", - - // We have to handle DOM nodes and JS objects differently because IE6-7 - // can't GC object references properly across the DOM-JS boundary - isNode = elem.nodeType, - - // Only DOM nodes need the global jQuery cache; JS object data is - // attached directly to the object so GC can occur automatically - cache = isNode ? jQuery.cache : elem, - - // Only defining an ID for JS objects if its cache already exists allows - // the code to shortcut on the same path as a DOM node with no cache - id = isNode ? elem[ internalKey ] : elem[ internalKey ] && internalKey, - isEvents = name === "events"; - - // Avoid doing any more work than we need to when trying to get data on an - // object that has no data at all - if ( (!id || !cache[id] || (!isEvents && !pvt && !cache[id].data)) && getByName && data === undefined ) { - return; - } - - if ( !id ) { - // Only DOM nodes need a new unique ID for each element since their data - // ends up in the global cache - if ( isNode ) { - elem[ internalKey ] = id = ++jQuery.uuid; - } else { - id = internalKey; - } - } - - if ( !cache[ id ] ) { - cache[ id ] = {}; - - // Avoids exposing jQuery metadata on plain JS objects when the object - // is serialized using JSON.stringify - if ( !isNode ) { - cache[ id ].toJSON = jQuery.noop; - } - } - - // An object can be passed to jQuery.data instead of a key/value pair; this gets - // shallow copied over onto the existing cache - if ( typeof name === "object" || typeof name === "function" ) { - if ( pvt ) { - cache[ id ] = jQuery.extend( cache[ id ], name ); - } else { - cache[ id ].data = jQuery.extend( cache[ id ].data, name ); - } - } - - privateCache = thisCache = cache[ id ]; - - // jQuery data() is stored in a separate object inside the object's internal data - // cache in order to avoid key collisions between internal data and user-defined - // data. - if ( !pvt ) { - if ( !thisCache.data ) { - thisCache.data = {}; - } - - thisCache = thisCache.data; - } - - if ( data !== undefined ) { - thisCache[ jQuery.camelCase( name ) ] = data; - } - - // Users should not attempt to inspect the internal events object using jQuery.data, - // it is undocumented and subject to change. But does anyone listen? No. - if ( isEvents && !thisCache[ name ] ) { - return privateCache.events; - } - - // Check for both converted-to-camel and non-converted data property names - // If a data property was specified - if ( getByName ) { - - // First Try to find as-is property data - ret = thisCache[ name ]; - - // Test for null|undefined property data - if ( ret == null ) { - - // Try to find the camelCased property - ret = thisCache[ jQuery.camelCase( name ) ]; - } - } else { - ret = thisCache; - } - - return ret; - }, - - removeData: function( elem, name, pvt /* Internal Use Only */ ) { - if ( !jQuery.acceptData( elem ) ) { - return; - } - - var thisCache, i, l, - - // Reference to internal data cache key - internalKey = jQuery.expando, - - isNode = elem.nodeType, - - // See jQuery.data for more information - cache = isNode ? jQuery.cache : elem, - - // See jQuery.data for more information - id = isNode ? elem[ internalKey ] : internalKey; - - // If there is already no cache entry for this object, there is no - // purpose in continuing - if ( !cache[ id ] ) { - return; - } - - if ( name ) { - - thisCache = pvt ? cache[ id ] : cache[ id ].data; - - if ( thisCache ) { - - // Support array or space separated string names for data keys - if ( !jQuery.isArray( name ) ) { - - // try the string as a key before any manipulation - if ( name in thisCache ) { - name = [ name ]; - } else { - - // split the camel cased version by spaces unless a key with the spaces exists - name = jQuery.camelCase( name ); - if ( name in thisCache ) { - name = [ name ]; - } else { - name = name.split( " " ); - } - } - } - - for ( i = 0, l = name.length; i < l; i++ ) { - delete thisCache[ name[i] ]; - } - - // If there is no data left in the cache, we want to continue - // and let the cache object itself get destroyed - if ( !( pvt ? isEmptyDataObject : jQuery.isEmptyObject )( thisCache ) ) { - return; - } - } - } - - // See jQuery.data for more information - if ( !pvt ) { - delete cache[ id ].data; - - // Don't destroy the parent cache unless the internal data object - // had been the only thing left in it - if ( !isEmptyDataObject(cache[ id ]) ) { - return; - } - } - - // Browsers that fail expando deletion also refuse to delete expandos on - // the window, but it will allow it on all other JS objects; other browsers - // don't care - // Ensure that `cache` is not a window object #10080 - if ( jQuery.support.deleteExpando || !cache.setInterval ) { - delete cache[ id ]; - } else { - cache[ id ] = null; - } - - // We destroyed the cache and need to eliminate the expando on the node to avoid - // false lookups in the cache for entries that no longer exist - if ( isNode ) { - // IE does not allow us to delete expando properties from nodes, - // nor does it have a removeAttribute function on Document nodes; - // we must handle all of these cases - if ( jQuery.support.deleteExpando ) { - delete elem[ internalKey ]; - } else if ( elem.removeAttribute ) { - elem.removeAttribute( internalKey ); - } else { - elem[ internalKey ] = null; - } - } - }, - - // For internal use only. - _data: function( elem, name, data ) { - return jQuery.data( elem, name, data, true ); - }, - - // A method for determining if a DOM node can handle the data expando - acceptData: function( elem ) { - if ( elem.nodeName ) { - var match = jQuery.noData[ elem.nodeName.toLowerCase() ]; - - if ( match ) { - return !(match === true || elem.getAttribute("classid") !== match); - } - } - - return true; - } -}); - -jQuery.fn.extend({ - data: function( key, value ) { - var parts, part, attr, name, l, - elem = this[0], - i = 0, - data = null; - - // Gets all values - if ( key === undefined ) { - if ( this.length ) { - data = jQuery.data( elem ); - - if ( elem.nodeType === 1 && !jQuery._data( elem, "parsedAttrs" ) ) { - attr = elem.attributes; - for ( l = attr.length; i < l; i++ ) { - name = attr[i].name; - - if ( name.indexOf( "data-" ) === 0 ) { - name = jQuery.camelCase( name.substring(5) ); - - dataAttr( elem, name, data[ name ] ); - } - } - jQuery._data( elem, "parsedAttrs", true ); - } - } - - return data; - } - - // Sets multiple values - if ( typeof key === "object" ) { - return this.each(function() { - jQuery.data( this, key ); - }); - } - - parts = key.split( ".", 2 ); - parts[1] = parts[1] ? "." + parts[1] : ""; - part = parts[1] + "!"; - - return jQuery.access( this, function( value ) { - - if ( value === undefined ) { - data = this.triggerHandler( "getData" + part, [ parts[0] ] ); - - // Try to fetch any internally stored data first - if ( data === undefined && elem ) { - data = jQuery.data( elem, key ); - data = dataAttr( elem, key, data ); - } - - return data === undefined && parts[1] ? - this.data( parts[0] ) : - data; - } - - parts[1] = value; - this.each(function() { - var self = jQuery( this ); - - self.triggerHandler( "setData" + part, parts ); - jQuery.data( this, key, value ); - self.triggerHandler( "changeData" + part, parts ); - }); - }, null, value, arguments.length > 1, null, false ); - }, - - removeData: function( key ) { - return this.each(function() { - jQuery.removeData( this, key ); - }); - } -}); - -function dataAttr( elem, key, data ) { - // If nothing was found internally, try to fetch any - // data from the HTML5 data-* attribute - if ( data === undefined && elem.nodeType === 1 ) { - - var name = "data-" + key.replace( rmultiDash, "-$1" ).toLowerCase(); - - data = elem.getAttribute( name ); - - if ( typeof data === "string" ) { - try { - data = data === "true" ? true : - data === "false" ? false : - data === "null" ? null : - jQuery.isNumeric( data ) ? +data : - rbrace.test( data ) ? jQuery.parseJSON( data ) : - data; - } catch( e ) {} - - // Make sure we set the data so it isn't changed later - jQuery.data( elem, key, data ); - - } else { - data = undefined; - } - } - - return data; -} - -// checks a cache object for emptiness -function isEmptyDataObject( obj ) { - for ( var name in obj ) { - - // if the public data object is empty, the private is still empty - if ( name === "data" && jQuery.isEmptyObject( obj[name] ) ) { - continue; - } - if ( name !== "toJSON" ) { - return false; - } - } - - return true; -} - - - - -function handleQueueMarkDefer( elem, type, src ) { - var deferDataKey = type + "defer", - queueDataKey = type + "queue", - markDataKey = type + "mark", - defer = jQuery._data( elem, deferDataKey ); - if ( defer && - ( src === "queue" || !jQuery._data(elem, queueDataKey) ) && - ( src === "mark" || !jQuery._data(elem, markDataKey) ) ) { - // Give room for hard-coded callbacks to fire first - // and eventually mark/queue something else on the element - setTimeout( function() { - if ( !jQuery._data( elem, queueDataKey ) && - !jQuery._data( elem, markDataKey ) ) { - jQuery.removeData( elem, deferDataKey, true ); - defer.fire(); - } - }, 0 ); - } -} - -jQuery.extend({ - - _mark: function( elem, type ) { - if ( elem ) { - type = ( type || "fx" ) + "mark"; - jQuery._data( elem, type, (jQuery._data( elem, type ) || 0) + 1 ); - } - }, - - _unmark: function( force, elem, type ) { - if ( force !== true ) { - type = elem; - elem = force; - force = false; - } - if ( elem ) { - type = type || "fx"; - var key = type + "mark", - count = force ? 0 : ( (jQuery._data( elem, key ) || 1) - 1 ); - if ( count ) { - jQuery._data( elem, key, count ); - } else { - jQuery.removeData( elem, key, true ); - handleQueueMarkDefer( elem, type, "mark" ); - } - } - }, - - queue: function( elem, type, data ) { - var q; - if ( elem ) { - type = ( type || "fx" ) + "queue"; - q = jQuery._data( elem, type ); - - // Speed up dequeue by getting out quickly if this is just a lookup - if ( data ) { - if ( !q || jQuery.isArray(data) ) { - q = jQuery._data( elem, type, jQuery.makeArray(data) ); - } else { - q.push( data ); - } - } - return q || []; - } - }, - - dequeue: function( elem, type ) { - type = type || "fx"; - - var queue = jQuery.queue( elem, type ), - fn = queue.shift(), - hooks = {}; - - // If the fx queue is dequeued, always remove the progress sentinel - if ( fn === "inprogress" ) { - fn = queue.shift(); - } - - if ( fn ) { - // Add a progress sentinel to prevent the fx queue from being - // automatically dequeued - if ( type === "fx" ) { - queue.unshift( "inprogress" ); - } - - jQuery._data( elem, type + ".run", hooks ); - fn.call( elem, function() { - jQuery.dequeue( elem, type ); - }, hooks ); - } - - if ( !queue.length ) { - jQuery.removeData( elem, type + "queue " + type + ".run", true ); - handleQueueMarkDefer( elem, type, "queue" ); - } - } -}); - -jQuery.fn.extend({ - queue: function( type, data ) { - var setter = 2; - - if ( typeof type !== "string" ) { - data = type; - type = "fx"; - setter--; - } - - if ( arguments.length < setter ) { - return jQuery.queue( this[0], type ); - } - - return data === undefined ? - this : - this.each(function() { - var queue = jQuery.queue( this, type, data ); - - if ( type === "fx" && queue[0] !== "inprogress" ) { - jQuery.dequeue( this, type ); - } - }); - }, - dequeue: function( type ) { - return this.each(function() { - jQuery.dequeue( this, type ); - }); - }, - // Based off of the plugin by Clint Helfers, with permission. - // http://blindsignals.com/index.php/2009/07/jquery-delay/ - delay: function( time, type ) { - time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time; - type = type || "fx"; - - return this.queue( type, function( next, hooks ) { - var timeout = setTimeout( next, time ); - hooks.stop = function() { - clearTimeout( timeout ); - }; - }); - }, - clearQueue: function( type ) { - return this.queue( type || "fx", [] ); - }, - // Get a promise resolved when queues of a certain type - // are emptied (fx is the type by default) - promise: function( type, object ) { - if ( typeof type !== "string" ) { - object = type; - type = undefined; - } - type = type || "fx"; - var defer = jQuery.Deferred(), - elements = this, - i = elements.length, - count = 1, - deferDataKey = type + "defer", - queueDataKey = type + "queue", - markDataKey = type + "mark", - tmp; - function resolve() { - if ( !( --count ) ) { - defer.resolveWith( elements, [ elements ] ); - } - } - while( i-- ) { - if (( tmp = jQuery.data( elements[ i ], deferDataKey, undefined, true ) || - ( jQuery.data( elements[ i ], queueDataKey, undefined, true ) || - jQuery.data( elements[ i ], markDataKey, undefined, true ) ) && - jQuery.data( elements[ i ], deferDataKey, jQuery.Callbacks( "once memory" ), true ) )) { - count++; - tmp.add( resolve ); - } - } - resolve(); - return defer.promise( object ); - } -}); - - - - -var rclass = /[\n\t\r]/g, - rspace = /\s+/, - rreturn = /\r/g, - rtype = /^(?:button|input)$/i, - rfocusable = /^(?:button|input|object|select|textarea)$/i, - rclickable = /^a(?:rea)?$/i, - rboolean = /^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i, - getSetAttribute = jQuery.support.getSetAttribute, - nodeHook, boolHook, fixSpecified; - -jQuery.fn.extend({ - attr: function( name, value ) { - return jQuery.access( this, jQuery.attr, name, value, arguments.length > 1 ); - }, - - removeAttr: function( name ) { - return this.each(function() { - jQuery.removeAttr( this, name ); - }); - }, - - prop: function( name, value ) { - return jQuery.access( this, jQuery.prop, name, value, arguments.length > 1 ); - }, - - removeProp: function( name ) { - name = jQuery.propFix[ name ] || name; - return this.each(function() { - // try/catch handles cases where IE balks (such as removing a property on window) - try { - this[ name ] = undefined; - delete this[ name ]; - } catch( e ) {} - }); - }, - - addClass: function( value ) { - var classNames, i, l, elem, - setClass, c, cl; - - if ( jQuery.isFunction( value ) ) { - return this.each(function( j ) { - jQuery( this ).addClass( value.call(this, j, this.className) ); - }); - } - - if ( value && typeof value === "string" ) { - classNames = value.split( rspace ); - - for ( i = 0, l = this.length; i < l; i++ ) { - elem = this[ i ]; - - if ( elem.nodeType === 1 ) { - if ( !elem.className && classNames.length === 1 ) { - elem.className = value; - - } else { - setClass = " " + elem.className + " "; - - for ( c = 0, cl = classNames.length; c < cl; c++ ) { - if ( !~setClass.indexOf( " " + classNames[ c ] + " " ) ) { - setClass += classNames[ c ] + " "; - } - } - elem.className = jQuery.trim( setClass ); - } - } - } - } - - return this; - }, - - removeClass: function( value ) { - var classNames, i, l, elem, className, c, cl; - - if ( jQuery.isFunction( value ) ) { - return this.each(function( j ) { - jQuery( this ).removeClass( value.call(this, j, this.className) ); - }); - } - - if ( (value && typeof value === "string") || value === undefined ) { - classNames = ( value || "" ).split( rspace ); - - for ( i = 0, l = this.length; i < l; i++ ) { - elem = this[ i ]; - - if ( elem.nodeType === 1 && elem.className ) { - if ( value ) { - className = (" " + elem.className + " ").replace( rclass, " " ); - for ( c = 0, cl = classNames.length; c < cl; c++ ) { - className = className.replace(" " + classNames[ c ] + " ", " "); - } - elem.className = jQuery.trim( className ); - - } else { - elem.className = ""; - } - } - } - } - - return this; - }, - - toggleClass: function( value, stateVal ) { - var type = typeof value, - isBool = typeof stateVal === "boolean"; - - if ( jQuery.isFunction( value ) ) { - return this.each(function( i ) { - jQuery( this ).toggleClass( value.call(this, i, this.className, stateVal), stateVal ); - }); - } - - return this.each(function() { - if ( type === "string" ) { - // toggle individual class names - var className, - i = 0, - self = jQuery( this ), - state = stateVal, - classNames = value.split( rspace ); - - while ( (className = classNames[ i++ ]) ) { - // check each className given, space seperated list - state = isBool ? state : !self.hasClass( className ); - self[ state ? "addClass" : "removeClass" ]( className ); - } - - } else if ( type === "undefined" || type === "boolean" ) { - if ( this.className ) { - // store className if set - jQuery._data( this, "__className__", this.className ); - } - - // toggle whole className - this.className = this.className || value === false ? "" : jQuery._data( this, "__className__" ) || ""; - } - }); - }, - - hasClass: function( selector ) { - var className = " " + selector + " ", - i = 0, - l = this.length; - for ( ; i < l; i++ ) { - if ( this[i].nodeType === 1 && (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) > -1 ) { - return true; - } - } - - return false; - }, - - val: function( value ) { - var hooks, ret, isFunction, - elem = this[0]; - - if ( !arguments.length ) { - if ( elem ) { - hooks = jQuery.valHooks[ elem.type ] || jQuery.valHooks[ elem.nodeName.toLowerCase() ]; - - if ( hooks && "get" in hooks && (ret = hooks.get( elem, "value" )) !== undefined ) { - return ret; - } - - ret = elem.value; - - return typeof ret === "string" ? - // handle most common string cases - ret.replace(rreturn, "") : - // handle cases where value is null/undef or number - ret == null ? "" : ret; - } - - return; - } - - isFunction = jQuery.isFunction( value ); - - return this.each(function( i ) { - var self = jQuery(this), val; - - if ( this.nodeType !== 1 ) { - return; - } - - if ( isFunction ) { - val = value.call( this, i, self.val() ); - } else { - val = value; - } - - // Treat null/undefined as ""; convert numbers to string - if ( val == null ) { - val = ""; - } else if ( typeof val === "number" ) { - val += ""; - } else if ( jQuery.isArray( val ) ) { - val = jQuery.map(val, function ( value ) { - return value == null ? "" : value + ""; - }); - } - - hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ]; - - // If set returns undefined, fall back to normal setting - if ( !hooks || !("set" in hooks) || hooks.set( this, val, "value" ) === undefined ) { - this.value = val; - } - }); - } -}); - -jQuery.extend({ - valHooks: { - option: { - get: function( elem ) { - // attributes.value is undefined in Blackberry 4.7 but - // uses .value. See #6932 - var val = elem.attributes.value; - return !val || val.specified ? elem.value : elem.text; - } - }, - select: { - get: function( elem ) { - var value, i, max, option, - index = elem.selectedIndex, - values = [], - options = elem.options, - one = elem.type === "select-one"; - - // Nothing was selected - if ( index < 0 ) { - return null; - } - - // Loop through all the selected options - i = one ? index : 0; - max = one ? index + 1 : options.length; - for ( ; i < max; i++ ) { - option = options[ i ]; - - // Don't return options that are disabled or in a disabled optgroup - if ( option.selected && (jQuery.support.optDisabled ? !option.disabled : option.getAttribute("disabled") === null) && - (!option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup" )) ) { - - // Get the specific value for the option - value = jQuery( option ).val(); - - // We don't need an array for one selects - if ( one ) { - return value; - } - - // Multi-Selects return an array - values.push( value ); - } - } - - // Fixes Bug #2551 -- select.val() broken in IE after form.reset() - if ( one && !values.length && options.length ) { - return jQuery( options[ index ] ).val(); - } - - return values; - }, - - set: function( elem, value ) { - var values = jQuery.makeArray( value ); - - jQuery(elem).find("option").each(function() { - this.selected = jQuery.inArray( jQuery(this).val(), values ) >= 0; - }); - - if ( !values.length ) { - elem.selectedIndex = -1; - } - return values; - } - } - }, - - attrFn: { - val: true, - css: true, - html: true, - text: true, - data: true, - width: true, - height: true, - offset: true - }, - - attr: function( elem, name, value, pass ) { - var ret, hooks, notxml, - nType = elem.nodeType; - - // don't get/set attributes on text, comment and attribute nodes - if ( !elem || nType === 3 || nType === 8 || nType === 2 ) { - return; - } - - if ( pass && name in jQuery.attrFn ) { - return jQuery( elem )[ name ]( value ); - } - - // Fallback to prop when attributes are not supported - if ( typeof elem.getAttribute === "undefined" ) { - return jQuery.prop( elem, name, value ); - } - - notxml = nType !== 1 || !jQuery.isXMLDoc( elem ); - - // All attributes are lowercase - // Grab necessary hook if one is defined - if ( notxml ) { - name = name.toLowerCase(); - hooks = jQuery.attrHooks[ name ] || ( rboolean.test( name ) ? boolHook : nodeHook ); - } - - if ( value !== undefined ) { - - if ( value === null ) { - jQuery.removeAttr( elem, name ); - return; - - } else if ( hooks && "set" in hooks && notxml && (ret = hooks.set( elem, value, name )) !== undefined ) { - return ret; - - } else { - elem.setAttribute( name, "" + value ); - return value; - } - - } else if ( hooks && "get" in hooks && notxml && (ret = hooks.get( elem, name )) !== null ) { - return ret; - - } else { - - ret = elem.getAttribute( name ); - - // Non-existent attributes return null, we normalize to undefined - return ret === null ? - undefined : - ret; - } - }, - - removeAttr: function( elem, value ) { - var propName, attrNames, name, l, isBool, - i = 0; - - if ( value && elem.nodeType === 1 ) { - attrNames = value.toLowerCase().split( rspace ); - l = attrNames.length; - - for ( ; i < l; i++ ) { - name = attrNames[ i ]; - - if ( name ) { - propName = jQuery.propFix[ name ] || name; - isBool = rboolean.test( name ); - - // See #9699 for explanation of this approach (setting first, then removal) - // Do not do this for boolean attributes (see #10870) - if ( !isBool ) { - jQuery.attr( elem, name, "" ); - } - elem.removeAttribute( getSetAttribute ? name : propName ); - - // Set corresponding property to false for boolean attributes - if ( isBool && propName in elem ) { - elem[ propName ] = false; - } - } - } - } - }, - - attrHooks: { - type: { - set: function( elem, value ) { - // We can't allow the type property to be changed (since it causes problems in IE) - if ( rtype.test( elem.nodeName ) && elem.parentNode ) { - jQuery.error( "type property can't be changed" ); - } else if ( !jQuery.support.radioValue && value === "radio" && jQuery.nodeName(elem, "input") ) { - // Setting the type on a radio button after the value resets the value in IE6-9 - // Reset value to it's default in case type is set after value - // This is for element creation - var val = elem.value; - elem.setAttribute( "type", value ); - if ( val ) { - elem.value = val; - } - return value; - } - } - }, - // Use the value property for back compat - // Use the nodeHook for button elements in IE6/7 (#1954) - value: { - get: function( elem, name ) { - if ( nodeHook && jQuery.nodeName( elem, "button" ) ) { - return nodeHook.get( elem, name ); - } - return name in elem ? - elem.value : - null; - }, - set: function( elem, value, name ) { - if ( nodeHook && jQuery.nodeName( elem, "button" ) ) { - return nodeHook.set( elem, value, name ); - } - // Does not return so that setAttribute is also used - elem.value = value; - } - } - }, - - propFix: { - tabindex: "tabIndex", - readonly: "readOnly", - "for": "htmlFor", - "class": "className", - maxlength: "maxLength", - cellspacing: "cellSpacing", - cellpadding: "cellPadding", - rowspan: "rowSpan", - colspan: "colSpan", - usemap: "useMap", - frameborder: "frameBorder", - contenteditable: "contentEditable" - }, - - prop: function( elem, name, value ) { - var ret, hooks, notxml, - nType = elem.nodeType; - - // don't get/set properties on text, comment and attribute nodes - if ( !elem || nType === 3 || nType === 8 || nType === 2 ) { - return; - } - - notxml = nType !== 1 || !jQuery.isXMLDoc( elem ); - - if ( notxml ) { - // Fix name and attach hooks - name = jQuery.propFix[ name ] || name; - hooks = jQuery.propHooks[ name ]; - } - - if ( value !== undefined ) { - if ( hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) { - return ret; - - } else { - return ( elem[ name ] = value ); - } - - } else { - if ( hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ) { - return ret; - - } else { - return elem[ name ]; - } - } - }, - - propHooks: { - tabIndex: { - get: function( elem ) { - // elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set - // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/ - var attributeNode = elem.getAttributeNode("tabindex"); - - return attributeNode && attributeNode.specified ? - parseInt( attributeNode.value, 10 ) : - rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ? - 0 : - undefined; - } - } - } -}); - -// Add the tabIndex propHook to attrHooks for back-compat (different case is intentional) -jQuery.attrHooks.tabindex = jQuery.propHooks.tabIndex; - -// Hook for boolean attributes -boolHook = { - get: function( elem, name ) { - // Align boolean attributes with corresponding properties - // Fall back to attribute presence where some booleans are not supported - var attrNode, - property = jQuery.prop( elem, name ); - return property === true || typeof property !== "boolean" && ( attrNode = elem.getAttributeNode(name) ) && attrNode.nodeValue !== false ? - name.toLowerCase() : - undefined; - }, - set: function( elem, value, name ) { - var propName; - if ( value === false ) { - // Remove boolean attributes when set to false - jQuery.removeAttr( elem, name ); - } else { - // value is true since we know at this point it's type boolean and not false - // Set boolean attributes to the same name and set the DOM property - propName = jQuery.propFix[ name ] || name; - if ( propName in elem ) { - // Only set the IDL specifically if it already exists on the element - elem[ propName ] = true; - } - - elem.setAttribute( name, name.toLowerCase() ); - } - return name; - } -}; - -// IE6/7 do not support getting/setting some attributes with get/setAttribute -if ( !getSetAttribute ) { - - fixSpecified = { - name: true, - id: true, - coords: true - }; - - // Use this for any attribute in IE6/7 - // This fixes almost every IE6/7 issue - nodeHook = jQuery.valHooks.button = { - get: function( elem, name ) { - var ret; - ret = elem.getAttributeNode( name ); - return ret && ( fixSpecified[ name ] ? ret.nodeValue !== "" : ret.specified ) ? - ret.nodeValue : - undefined; - }, - set: function( elem, value, name ) { - // Set the existing or create a new attribute node - var ret = elem.getAttributeNode( name ); - if ( !ret ) { - ret = document.createAttribute( name ); - elem.setAttributeNode( ret ); - } - return ( ret.nodeValue = value + "" ); - } - }; - - // Apply the nodeHook to tabindex - jQuery.attrHooks.tabindex.set = nodeHook.set; - - // Set width and height to auto instead of 0 on empty string( Bug #8150 ) - // This is for removals - jQuery.each([ "width", "height" ], function( i, name ) { - jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], { - set: function( elem, value ) { - if ( value === "" ) { - elem.setAttribute( name, "auto" ); - return value; - } - } - }); - }); - - // Set contenteditable to false on removals(#10429) - // Setting to empty string throws an error as an invalid value - jQuery.attrHooks.contenteditable = { - get: nodeHook.get, - set: function( elem, value, name ) { - if ( value === "" ) { - value = "false"; - } - nodeHook.set( elem, value, name ); - } - }; -} - - -// Some attributes require a special call on IE -if ( !jQuery.support.hrefNormalized ) { - jQuery.each([ "href", "src", "width", "height" ], function( i, name ) { - jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], { - get: function( elem ) { - var ret = elem.getAttribute( name, 2 ); - return ret === null ? undefined : ret; - } - }); - }); -} - -if ( !jQuery.support.style ) { - jQuery.attrHooks.style = { - get: function( elem ) { - // Return undefined in the case of empty string - // Normalize to lowercase since IE uppercases css property names - return elem.style.cssText.toLowerCase() || undefined; - }, - set: function( elem, value ) { - return ( elem.style.cssText = "" + value ); - } - }; -} - -// Safari mis-reports the default selected property of an option -// Accessing the parent's selectedIndex property fixes it -if ( !jQuery.support.optSelected ) { - jQuery.propHooks.selected = jQuery.extend( jQuery.propHooks.selected, { - get: function( elem ) { - var parent = elem.parentNode; - - if ( parent ) { - parent.selectedIndex; - - // Make sure that it also works with optgroups, see #5701 - if ( parent.parentNode ) { - parent.parentNode.selectedIndex; - } - } - return null; - } - }); -} - -// IE6/7 call enctype encoding -if ( !jQuery.support.enctype ) { - jQuery.propFix.enctype = "encoding"; -} - -// Radios and checkboxes getter/setter -if ( !jQuery.support.checkOn ) { - jQuery.each([ "radio", "checkbox" ], function() { - jQuery.valHooks[ this ] = { - get: function( elem ) { - // Handle the case where in Webkit "" is returned instead of "on" if a value isn't specified - return elem.getAttribute("value") === null ? "on" : elem.value; - } - }; - }); -} -jQuery.each([ "radio", "checkbox" ], function() { - jQuery.valHooks[ this ] = jQuery.extend( jQuery.valHooks[ this ], { - set: function( elem, value ) { - if ( jQuery.isArray( value ) ) { - return ( elem.checked = jQuery.inArray( jQuery(elem).val(), value ) >= 0 ); - } - } - }); -}); - - - - -var rformElems = /^(?:textarea|input|select)$/i, - rtypenamespace = /^([^\.]*)?(?:\.(.+))?$/, - rhoverHack = /(?:^|\s)hover(\.\S+)?\b/, - rkeyEvent = /^key/, - rmouseEvent = /^(?:mouse|contextmenu)|click/, - rfocusMorph = /^(?:focusinfocus|focusoutblur)$/, - rquickIs = /^(\w*)(?:#([\w\-]+))?(?:\.([\w\-]+))?$/, - quickParse = function( selector ) { - var quick = rquickIs.exec( selector ); - if ( quick ) { - // 0 1 2 3 - // [ _, tag, id, class ] - quick[1] = ( quick[1] || "" ).toLowerCase(); - quick[3] = quick[3] && new RegExp( "(?:^|\\s)" + quick[3] + "(?:\\s|$)" ); - } - return quick; - }, - quickIs = function( elem, m ) { - var attrs = elem.attributes || {}; - return ( - (!m[1] || elem.nodeName.toLowerCase() === m[1]) && - (!m[2] || (attrs.id || {}).value === m[2]) && - (!m[3] || m[3].test( (attrs[ "class" ] || {}).value )) - ); - }, - hoverHack = function( events ) { - return jQuery.event.special.hover ? events : events.replace( rhoverHack, "mouseenter$1 mouseleave$1" ); - }; - -/* - * Helper functions for managing events -- not part of the public interface. - * Props to Dean Edwards' addEvent library for many of the ideas. - */ -jQuery.event = { - - add: function( elem, types, handler, data, selector ) { - - var elemData, eventHandle, events, - t, tns, type, namespaces, handleObj, - handleObjIn, quick, handlers, special; - - // Don't attach events to noData or text/comment nodes (allow plain objects tho) - if ( elem.nodeType === 3 || elem.nodeType === 8 || !types || !handler || !(elemData = jQuery._data( elem )) ) { - return; - } - - // Caller can pass in an object of custom data in lieu of the handler - if ( handler.handler ) { - handleObjIn = handler; - handler = handleObjIn.handler; - selector = handleObjIn.selector; - } - - // Make sure that the handler has a unique ID, used to find/remove it later - if ( !handler.guid ) { - handler.guid = jQuery.guid++; - } - - // Init the element's event structure and main handler, if this is the first - events = elemData.events; - if ( !events ) { - elemData.events = events = {}; - } - eventHandle = elemData.handle; - if ( !eventHandle ) { - elemData.handle = eventHandle = function( e ) { - // Discard the second event of a jQuery.event.trigger() and - // when an event is called after a page has unloaded - return typeof jQuery !== "undefined" && (!e || jQuery.event.triggered !== e.type) ? - jQuery.event.dispatch.apply( eventHandle.elem, arguments ) : - undefined; - }; - // Add elem as a property of the handle fn to prevent a memory leak with IE non-native events - eventHandle.elem = elem; - } - - // Handle multiple events separated by a space - // jQuery(...).bind("mouseover mouseout", fn); - types = jQuery.trim( hoverHack(types) ).split( " " ); - for ( t = 0; t < types.length; t++ ) { - - tns = rtypenamespace.exec( types[t] ) || []; - type = tns[1]; - namespaces = ( tns[2] || "" ).split( "." ).sort(); - - // If event changes its type, use the special event handlers for the changed type - special = jQuery.event.special[ type ] || {}; - - // If selector defined, determine special event api type, otherwise given type - type = ( selector ? special.delegateType : special.bindType ) || type; - - // Update special based on newly reset type - special = jQuery.event.special[ type ] || {}; - - // handleObj is passed to all event handlers - handleObj = jQuery.extend({ - type: type, - origType: tns[1], - data: data, - handler: handler, - guid: handler.guid, - selector: selector, - quick: selector && quickParse( selector ), - namespace: namespaces.join(".") - }, handleObjIn ); - - // Init the event handler queue if we're the first - handlers = events[ type ]; - if ( !handlers ) { - handlers = events[ type ] = []; - handlers.delegateCount = 0; - - // Only use addEventListener/attachEvent if the special events handler returns false - if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) { - // Bind the global event handler to the element - if ( elem.addEventListener ) { - elem.addEventListener( type, eventHandle, false ); - - } else if ( elem.attachEvent ) { - elem.attachEvent( "on" + type, eventHandle ); - } - } - } - - if ( special.add ) { - special.add.call( elem, handleObj ); - - if ( !handleObj.handler.guid ) { - handleObj.handler.guid = handler.guid; - } - } - - // Add to the element's handler list, delegates in front - if ( selector ) { - handlers.splice( handlers.delegateCount++, 0, handleObj ); - } else { - handlers.push( handleObj ); - } - - // Keep track of which events have ever been used, for event optimization - jQuery.event.global[ type ] = true; - } - - // Nullify elem to prevent memory leaks in IE - elem = null; - }, - - global: {}, - - // Detach an event or set of events from an element - remove: function( elem, types, handler, selector, mappedTypes ) { - - var elemData = jQuery.hasData( elem ) && jQuery._data( elem ), - t, tns, type, origType, namespaces, origCount, - j, events, special, handle, eventType, handleObj; - - if ( !elemData || !(events = elemData.events) ) { - return; - } - - // Once for each type.namespace in types; type may be omitted - types = jQuery.trim( hoverHack( types || "" ) ).split(" "); - for ( t = 0; t < types.length; t++ ) { - tns = rtypenamespace.exec( types[t] ) || []; - type = origType = tns[1]; - namespaces = tns[2]; - - // Unbind all events (on this namespace, if provided) for the element - if ( !type ) { - for ( type in events ) { - jQuery.event.remove( elem, type + types[ t ], handler, selector, true ); - } - continue; - } - - special = jQuery.event.special[ type ] || {}; - type = ( selector? special.delegateType : special.bindType ) || type; - eventType = events[ type ] || []; - origCount = eventType.length; - namespaces = namespaces ? new RegExp("(^|\\.)" + namespaces.split(".").sort().join("\\.(?:.*\\.)?") + "(\\.|$)") : null; - - // Remove matching events - for ( j = 0; j < eventType.length; j++ ) { - handleObj = eventType[ j ]; - - if ( ( mappedTypes || origType === handleObj.origType ) && - ( !handler || handler.guid === handleObj.guid ) && - ( !namespaces || namespaces.test( handleObj.namespace ) ) && - ( !selector || selector === handleObj.selector || selector === "**" && handleObj.selector ) ) { - eventType.splice( j--, 1 ); - - if ( handleObj.selector ) { - eventType.delegateCount--; - } - if ( special.remove ) { - special.remove.call( elem, handleObj ); - } - } - } - - // Remove generic event handler if we removed something and no more handlers exist - // (avoids potential for endless recursion during removal of special event handlers) - if ( eventType.length === 0 && origCount !== eventType.length ) { - if ( !special.teardown || special.teardown.call( elem, namespaces ) === false ) { - jQuery.removeEvent( elem, type, elemData.handle ); - } - - delete events[ type ]; - } - } - - // Remove the expando if it's no longer used - if ( jQuery.isEmptyObject( events ) ) { - handle = elemData.handle; - if ( handle ) { - handle.elem = null; - } - - // removeData also checks for emptiness and clears the expando if empty - // so use it instead of delete - jQuery.removeData( elem, [ "events", "handle" ], true ); - } - }, - - // Events that are safe to short-circuit if no handlers are attached. - // Native DOM events should not be added, they may have inline handlers. - customEvent: { - "getData": true, - "setData": true, - "changeData": true - }, - - trigger: function( event, data, elem, onlyHandlers ) { - // Don't do events on text and comment nodes - if ( elem && (elem.nodeType === 3 || elem.nodeType === 8) ) { - return; - } - - // Event object or event type - var type = event.type || event, - namespaces = [], - cache, exclusive, i, cur, old, ontype, special, handle, eventPath, bubbleType; - - // focus/blur morphs to focusin/out; ensure we're not firing them right now - if ( rfocusMorph.test( type + jQuery.event.triggered ) ) { - return; - } - - if ( type.indexOf( "!" ) >= 0 ) { - // Exclusive events trigger only for the exact event (no namespaces) - type = type.slice(0, -1); - exclusive = true; - } - - if ( type.indexOf( "." ) >= 0 ) { - // Namespaced trigger; create a regexp to match event type in handle() - namespaces = type.split("."); - type = namespaces.shift(); - namespaces.sort(); - } - - if ( (!elem || jQuery.event.customEvent[ type ]) && !jQuery.event.global[ type ] ) { - // No jQuery handlers for this event type, and it can't have inline handlers - return; - } - - // Caller can pass in an Event, Object, or just an event type string - event = typeof event === "object" ? - // jQuery.Event object - event[ jQuery.expando ] ? event : - // Object literal - new jQuery.Event( type, event ) : - // Just the event type (string) - new jQuery.Event( type ); - - event.type = type; - event.isTrigger = true; - event.exclusive = exclusive; - event.namespace = namespaces.join( "." ); - event.namespace_re = event.namespace? new RegExp("(^|\\.)" + namespaces.join("\\.(?:.*\\.)?") + "(\\.|$)") : null; - ontype = type.indexOf( ":" ) < 0 ? "on" + type : ""; - - // Handle a global trigger - if ( !elem ) { - - // TODO: Stop taunting the data cache; remove global events and always attach to document - cache = jQuery.cache; - for ( i in cache ) { - if ( cache[ i ].events && cache[ i ].events[ type ] ) { - jQuery.event.trigger( event, data, cache[ i ].handle.elem, true ); - } - } - return; - } - - // Clean up the event in case it is being reused - event.result = undefined; - if ( !event.target ) { - event.target = elem; - } - - // Clone any incoming data and prepend the event, creating the handler arg list - data = data != null ? jQuery.makeArray( data ) : []; - data.unshift( event ); - - // Allow special events to draw outside the lines - special = jQuery.event.special[ type ] || {}; - if ( special.trigger && special.trigger.apply( elem, data ) === false ) { - return; - } - - // Determine event propagation path in advance, per W3C events spec (#9951) - // Bubble up to document, then to window; watch for a global ownerDocument var (#9724) - eventPath = [[ elem, special.bindType || type ]]; - if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) { - - bubbleType = special.delegateType || type; - cur = rfocusMorph.test( bubbleType + type ) ? elem : elem.parentNode; - old = null; - for ( ; cur; cur = cur.parentNode ) { - eventPath.push([ cur, bubbleType ]); - old = cur; - } - - // Only add window if we got to document (e.g., not plain obj or detached DOM) - if ( old && old === elem.ownerDocument ) { - eventPath.push([ old.defaultView || old.parentWindow || window, bubbleType ]); - } - } - - // Fire handlers on the event path - for ( i = 0; i < eventPath.length && !event.isPropagationStopped(); i++ ) { - - cur = eventPath[i][0]; - event.type = eventPath[i][1]; - - handle = ( jQuery._data( cur, "events" ) || {} )[ event.type ] && jQuery._data( cur, "handle" ); - if ( handle ) { - handle.apply( cur, data ); - } - // Note that this is a bare JS function and not a jQuery handler - handle = ontype && cur[ ontype ]; - if ( handle && jQuery.acceptData( cur ) && handle.apply( cur, data ) === false ) { - event.preventDefault(); - } - } - event.type = type; - - // If nobody prevented the default action, do it now - if ( !onlyHandlers && !event.isDefaultPrevented() ) { - - if ( (!special._default || special._default.apply( elem.ownerDocument, data ) === false) && - !(type === "click" && jQuery.nodeName( elem, "a" )) && jQuery.acceptData( elem ) ) { - - // Call a native DOM method on the target with the same name name as the event. - // Can't use an .isFunction() check here because IE6/7 fails that test. - // Don't do default actions on window, that's where global variables be (#6170) - // IE<9 dies on focus/blur to hidden element (#1486) - if ( ontype && elem[ type ] && ((type !== "focus" && type !== "blur") || event.target.offsetWidth !== 0) && !jQuery.isWindow( elem ) ) { - - // Don't re-trigger an onFOO event when we call its FOO() method - old = elem[ ontype ]; - - if ( old ) { - elem[ ontype ] = null; - } - - // Prevent re-triggering of the same event, since we already bubbled it above - jQuery.event.triggered = type; - elem[ type ](); - jQuery.event.triggered = undefined; - - if ( old ) { - elem[ ontype ] = old; - } - } - } - } - - return event.result; - }, - - dispatch: function( event ) { - - // Make a writable jQuery.Event from the native event object - event = jQuery.event.fix( event || window.event ); - - var handlers = ( (jQuery._data( this, "events" ) || {} )[ event.type ] || []), - delegateCount = handlers.delegateCount, - args = [].slice.call( arguments, 0 ), - run_all = !event.exclusive && !event.namespace, - special = jQuery.event.special[ event.type ] || {}, - handlerQueue = [], - i, j, cur, jqcur, ret, selMatch, matched, matches, handleObj, sel, related; - - // Use the fix-ed jQuery.Event rather than the (read-only) native event - args[0] = event; - event.delegateTarget = this; - - // Call the preDispatch hook for the mapped type, and let it bail if desired - if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) { - return; - } - - // Determine handlers that should run if there are delegated events - // Avoid non-left-click bubbling in Firefox (#3861) - if ( delegateCount && !(event.button && event.type === "click") ) { - - // Pregenerate a single jQuery object for reuse with .is() - jqcur = jQuery(this); - jqcur.context = this.ownerDocument || this; - - for ( cur = event.target; cur != this; cur = cur.parentNode || this ) { - - // Don't process events on disabled elements (#6911, #8165) - if ( cur.disabled !== true ) { - selMatch = {}; - matches = []; - jqcur[0] = cur; - for ( i = 0; i < delegateCount; i++ ) { - handleObj = handlers[ i ]; - sel = handleObj.selector; - - if ( selMatch[ sel ] === undefined ) { - selMatch[ sel ] = ( - handleObj.quick ? quickIs( cur, handleObj.quick ) : jqcur.is( sel ) - ); - } - if ( selMatch[ sel ] ) { - matches.push( handleObj ); - } - } - if ( matches.length ) { - handlerQueue.push({ elem: cur, matches: matches }); - } - } - } - } - - // Add the remaining (directly-bound) handlers - if ( handlers.length > delegateCount ) { - handlerQueue.push({ elem: this, matches: handlers.slice( delegateCount ) }); - } - - // Run delegates first; they may want to stop propagation beneath us - for ( i = 0; i < handlerQueue.length && !event.isPropagationStopped(); i++ ) { - matched = handlerQueue[ i ]; - event.currentTarget = matched.elem; - - for ( j = 0; j < matched.matches.length && !event.isImmediatePropagationStopped(); j++ ) { - handleObj = matched.matches[ j ]; - - // Triggered event must either 1) be non-exclusive and have no namespace, or - // 2) have namespace(s) a subset or equal to those in the bound event (both can have no namespace). - if ( run_all || (!event.namespace && !handleObj.namespace) || event.namespace_re && event.namespace_re.test( handleObj.namespace ) ) { - - event.data = handleObj.data; - event.handleObj = handleObj; - - ret = ( (jQuery.event.special[ handleObj.origType ] || {}).handle || handleObj.handler ) - .apply( matched.elem, args ); - - if ( ret !== undefined ) { - event.result = ret; - if ( ret === false ) { - event.preventDefault(); - event.stopPropagation(); - } - } - } - } - } - - // Call the postDispatch hook for the mapped type - if ( special.postDispatch ) { - special.postDispatch.call( this, event ); - } - - return event.result; - }, - - // Includes some event props shared by KeyEvent and MouseEvent - // *** attrChange attrName relatedNode srcElement are not normalized, non-W3C, deprecated, will be removed in 1.8 *** - props: "attrChange attrName relatedNode srcElement altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "), - - fixHooks: {}, - - keyHooks: { - props: "char charCode key keyCode".split(" "), - filter: function( event, original ) { - - // Add which for key events - if ( event.which == null ) { - event.which = original.charCode != null ? original.charCode : original.keyCode; - } - - return event; - } - }, - - mouseHooks: { - props: "button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "), - filter: function( event, original ) { - var eventDoc, doc, body, - button = original.button, - fromElement = original.fromElement; - - // Calculate pageX/Y if missing and clientX/Y available - if ( event.pageX == null && original.clientX != null ) { - eventDoc = event.target.ownerDocument || document; - doc = eventDoc.documentElement; - body = eventDoc.body; - - event.pageX = original.clientX + ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) - ( doc && doc.clientLeft || body && body.clientLeft || 0 ); - event.pageY = original.clientY + ( doc && doc.scrollTop || body && body.scrollTop || 0 ) - ( doc && doc.clientTop || body && body.clientTop || 0 ); - } - - // Add relatedTarget, if necessary - if ( !event.relatedTarget && fromElement ) { - event.relatedTarget = fromElement === event.target ? original.toElement : fromElement; - } - - // Add which for click: 1 === left; 2 === middle; 3 === right - // Note: button is not normalized, so don't use it - if ( !event.which && button !== undefined ) { - event.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) ); - } - - return event; - } - }, - - fix: function( event ) { - if ( event[ jQuery.expando ] ) { - return event; - } - - // Create a writable copy of the event object and normalize some properties - var i, prop, - originalEvent = event, - fixHook = jQuery.event.fixHooks[ event.type ] || {}, - copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props; - - event = jQuery.Event( originalEvent ); - - for ( i = copy.length; i; ) { - prop = copy[ --i ]; - event[ prop ] = originalEvent[ prop ]; - } - - // Fix target property, if necessary (#1925, IE 6/7/8 & Safari2) - if ( !event.target ) { - event.target = originalEvent.srcElement || document; - } - - // Target should not be a text node (#504, Safari) - if ( event.target.nodeType === 3 ) { - event.target = event.target.parentNode; - } - - // For mouse/key events; add metaKey if it's not there (#3368, IE6/7/8) - if ( event.metaKey === undefined ) { - event.metaKey = event.ctrlKey; - } - - return fixHook.filter? fixHook.filter( event, originalEvent ) : event; - }, - - special: { - ready: { - // Make sure the ready event is setup - setup: jQuery.bindReady - }, - - load: { - // Prevent triggered image.load events from bubbling to window.load - noBubble: true - }, - - focus: { - delegateType: "focusin" - }, - blur: { - delegateType: "focusout" - }, - - beforeunload: { - setup: function( data, namespaces, eventHandle ) { - // We only want to do this special case on windows - if ( jQuery.isWindow( this ) ) { - this.onbeforeunload = eventHandle; - } - }, - - teardown: function( namespaces, eventHandle ) { - if ( this.onbeforeunload === eventHandle ) { - this.onbeforeunload = null; - } - } - } - }, - - simulate: function( type, elem, event, bubble ) { - // Piggyback on a donor event to simulate a different one. - // Fake originalEvent to avoid donor's stopPropagation, but if the - // simulated event prevents default then we do the same on the donor. - var e = jQuery.extend( - new jQuery.Event(), - event, - { type: type, - isSimulated: true, - originalEvent: {} - } - ); - if ( bubble ) { - jQuery.event.trigger( e, null, elem ); - } else { - jQuery.event.dispatch.call( elem, e ); - } - if ( e.isDefaultPrevented() ) { - event.preventDefault(); - } - } -}; - -// Some plugins are using, but it's undocumented/deprecated and will be removed. -// The 1.7 special event interface should provide all the hooks needed now. -jQuery.event.handle = jQuery.event.dispatch; - -jQuery.removeEvent = document.removeEventListener ? - function( elem, type, handle ) { - if ( elem.removeEventListener ) { - elem.removeEventListener( type, handle, false ); - } - } : - function( elem, type, handle ) { - if ( elem.detachEvent ) { - elem.detachEvent( "on" + type, handle ); - } - }; - -jQuery.Event = function( src, props ) { - // Allow instantiation without the 'new' keyword - if ( !(this instanceof jQuery.Event) ) { - return new jQuery.Event( src, props ); - } - - // Event object - if ( src && src.type ) { - this.originalEvent = src; - this.type = src.type; - - // Events bubbling up the document may have been marked as prevented - // by a handler lower down the tree; reflect the correct value. - this.isDefaultPrevented = ( src.defaultPrevented || src.returnValue === false || - src.getPreventDefault && src.getPreventDefault() ) ? returnTrue : returnFalse; - - // Event type - } else { - this.type = src; - } - - // Put explicitly provided properties onto the event object - if ( props ) { - jQuery.extend( this, props ); - } - - // Create a timestamp if incoming event doesn't have one - this.timeStamp = src && src.timeStamp || jQuery.now(); - - // Mark it as fixed - this[ jQuery.expando ] = true; -}; - -function returnFalse() { - return false; -} -function returnTrue() { - return true; -} - -// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding -// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html -jQuery.Event.prototype = { - preventDefault: function() { - this.isDefaultPrevented = returnTrue; - - var e = this.originalEvent; - if ( !e ) { - return; - } - - // if preventDefault exists run it on the original event - if ( e.preventDefault ) { - e.preventDefault(); - - // otherwise set the returnValue property of the original event to false (IE) - } else { - e.returnValue = false; - } - }, - stopPropagation: function() { - this.isPropagationStopped = returnTrue; - - var e = this.originalEvent; - if ( !e ) { - return; - } - // if stopPropagation exists run it on the original event - if ( e.stopPropagation ) { - e.stopPropagation(); - } - // otherwise set the cancelBubble property of the original event to true (IE) - e.cancelBubble = true; - }, - stopImmediatePropagation: function() { - this.isImmediatePropagationStopped = returnTrue; - this.stopPropagation(); - }, - isDefaultPrevented: returnFalse, - isPropagationStopped: returnFalse, - isImmediatePropagationStopped: returnFalse -}; - -// Create mouseenter/leave events using mouseover/out and event-time checks -jQuery.each({ - mouseenter: "mouseover", - mouseleave: "mouseout" -}, function( orig, fix ) { - jQuery.event.special[ orig ] = { - delegateType: fix, - bindType: fix, - - handle: function( event ) { - var target = this, - related = event.relatedTarget, - handleObj = event.handleObj, - selector = handleObj.selector, - ret; - - // For mousenter/leave call the handler if related is outside the target. - // NB: No relatedTarget if the mouse left/entered the browser window - if ( !related || (related !== target && !jQuery.contains( target, related )) ) { - event.type = handleObj.origType; - ret = handleObj.handler.apply( this, arguments ); - event.type = fix; - } - return ret; - } - }; -}); - -// IE submit delegation -if ( !jQuery.support.submitBubbles ) { - - jQuery.event.special.submit = { - setup: function() { - // Only need this for delegated form submit events - if ( jQuery.nodeName( this, "form" ) ) { - return false; - } - - // Lazy-add a submit handler when a descendant form may potentially be submitted - jQuery.event.add( this, "click._submit keypress._submit", function( e ) { - // Node name check avoids a VML-related crash in IE (#9807) - var elem = e.target, - form = jQuery.nodeName( elem, "input" ) || jQuery.nodeName( elem, "button" ) ? elem.form : undefined; - if ( form && !form._submit_attached ) { - jQuery.event.add( form, "submit._submit", function( event ) { - event._submit_bubble = true; - }); - form._submit_attached = true; - } - }); - // return undefined since we don't need an event listener - }, - - postDispatch: function( event ) { - // If form was submitted by the user, bubble the event up the tree - if ( event._submit_bubble ) { - delete event._submit_bubble; - if ( this.parentNode && !event.isTrigger ) { - jQuery.event.simulate( "submit", this.parentNode, event, true ); - } - } - }, - - teardown: function() { - // Only need this for delegated form submit events - if ( jQuery.nodeName( this, "form" ) ) { - return false; - } - - // Remove delegated handlers; cleanData eventually reaps submit handlers attached above - jQuery.event.remove( this, "._submit" ); - } - }; -} - -// IE change delegation and checkbox/radio fix -if ( !jQuery.support.changeBubbles ) { - - jQuery.event.special.change = { - - setup: function() { - - if ( rformElems.test( this.nodeName ) ) { - // IE doesn't fire change on a check/radio until blur; trigger it on click - // after a propertychange. Eat the blur-change in special.change.handle. - // This still fires onchange a second time for check/radio after blur. - if ( this.type === "checkbox" || this.type === "radio" ) { - jQuery.event.add( this, "propertychange._change", function( event ) { - if ( event.originalEvent.propertyName === "checked" ) { - this._just_changed = true; - } - }); - jQuery.event.add( this, "click._change", function( event ) { - if ( this._just_changed && !event.isTrigger ) { - this._just_changed = false; - jQuery.event.simulate( "change", this, event, true ); - } - }); - } - return false; - } - // Delegated event; lazy-add a change handler on descendant inputs - jQuery.event.add( this, "beforeactivate._change", function( e ) { - var elem = e.target; - - if ( rformElems.test( elem.nodeName ) && !elem._change_attached ) { - jQuery.event.add( elem, "change._change", function( event ) { - if ( this.parentNode && !event.isSimulated && !event.isTrigger ) { - jQuery.event.simulate( "change", this.parentNode, event, true ); - } - }); - elem._change_attached = true; - } - }); - }, - - handle: function( event ) { - var elem = event.target; - - // Swallow native change events from checkbox/radio, we already triggered them above - if ( this !== elem || event.isSimulated || event.isTrigger || (elem.type !== "radio" && elem.type !== "checkbox") ) { - return event.handleObj.handler.apply( this, arguments ); - } - }, - - teardown: function() { - jQuery.event.remove( this, "._change" ); - - return rformElems.test( this.nodeName ); - } - }; -} - -// Create "bubbling" focus and blur events -if ( !jQuery.support.focusinBubbles ) { - jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) { - - // Attach a single capturing handler while someone wants focusin/focusout - var attaches = 0, - handler = function( event ) { - jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ), true ); - }; - - jQuery.event.special[ fix ] = { - setup: function() { - if ( attaches++ === 0 ) { - document.addEventListener( orig, handler, true ); - } - }, - teardown: function() { - if ( --attaches === 0 ) { - document.removeEventListener( orig, handler, true ); - } - } - }; - }); -} - -jQuery.fn.extend({ - - on: function( types, selector, data, fn, /*INTERNAL*/ one ) { - var origFn, type; - - // Types can be a map of types/handlers - if ( typeof types === "object" ) { - // ( types-Object, selector, data ) - if ( typeof selector !== "string" ) { // && selector != null - // ( types-Object, data ) - data = data || selector; - selector = undefined; - } - for ( type in types ) { - this.on( type, selector, data, types[ type ], one ); - } - return this; - } - - if ( data == null && fn == null ) { - // ( types, fn ) - fn = selector; - data = selector = undefined; - } else if ( fn == null ) { - if ( typeof selector === "string" ) { - // ( types, selector, fn ) - fn = data; - data = undefined; - } else { - // ( types, data, fn ) - fn = data; - data = selector; - selector = undefined; - } - } - if ( fn === false ) { - fn = returnFalse; - } else if ( !fn ) { - return this; - } - - if ( one === 1 ) { - origFn = fn; - fn = function( event ) { - // Can use an empty set, since event contains the info - jQuery().off( event ); - return origFn.apply( this, arguments ); - }; - // Use same guid so caller can remove using origFn - fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ ); - } - return this.each( function() { - jQuery.event.add( this, types, fn, data, selector ); - }); - }, - one: function( types, selector, data, fn ) { - return this.on( types, selector, data, fn, 1 ); - }, - off: function( types, selector, fn ) { - if ( types && types.preventDefault && types.handleObj ) { - // ( event ) dispatched jQuery.Event - var handleObj = types.handleObj; - jQuery( types.delegateTarget ).off( - handleObj.namespace ? handleObj.origType + "." + handleObj.namespace : handleObj.origType, - handleObj.selector, - handleObj.handler - ); - return this; - } - if ( typeof types === "object" ) { - // ( types-object [, selector] ) - for ( var type in types ) { - this.off( type, selector, types[ type ] ); - } - return this; - } - if ( selector === false || typeof selector === "function" ) { - // ( types [, fn] ) - fn = selector; - selector = undefined; - } - if ( fn === false ) { - fn = returnFalse; - } - return this.each(function() { - jQuery.event.remove( this, types, fn, selector ); - }); - }, - - bind: function( types, data, fn ) { - return this.on( types, null, data, fn ); - }, - unbind: function( types, fn ) { - return this.off( types, null, fn ); - }, - - live: function( types, data, fn ) { - jQuery( this.context ).on( types, this.selector, data, fn ); - return this; - }, - die: function( types, fn ) { - jQuery( this.context ).off( types, this.selector || "**", fn ); - return this; - }, - - delegate: function( selector, types, data, fn ) { - return this.on( types, selector, data, fn ); - }, - undelegate: function( selector, types, fn ) { - // ( namespace ) or ( selector, types [, fn] ) - return arguments.length == 1? this.off( selector, "**" ) : this.off( types, selector, fn ); - }, - - trigger: function( type, data ) { - return this.each(function() { - jQuery.event.trigger( type, data, this ); - }); - }, - triggerHandler: function( type, data ) { - if ( this[0] ) { - return jQuery.event.trigger( type, data, this[0], true ); - } - }, - - toggle: function( fn ) { - // Save reference to arguments for access in closure - var args = arguments, - guid = fn.guid || jQuery.guid++, - i = 0, - toggler = function( event ) { - // Figure out which function to execute - var lastToggle = ( jQuery._data( this, "lastToggle" + fn.guid ) || 0 ) % i; - jQuery._data( this, "lastToggle" + fn.guid, lastToggle + 1 ); - - // Make sure that clicks stop - event.preventDefault(); - - // and execute the function - return args[ lastToggle ].apply( this, arguments ) || false; - }; - - // link all the functions, so any of them can unbind this click handler - toggler.guid = guid; - while ( i < args.length ) { - args[ i++ ].guid = guid; - } - - return this.click( toggler ); - }, - - hover: function( fnOver, fnOut ) { - return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver ); - } -}); - -jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblclick " + - "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " + - "change select submit keydown keypress keyup error contextmenu").split(" "), function( i, name ) { - - // Handle event binding - jQuery.fn[ name ] = function( data, fn ) { - if ( fn == null ) { - fn = data; - data = null; - } - - return arguments.length > 0 ? - this.on( name, null, data, fn ) : - this.trigger( name ); - }; - - if ( jQuery.attrFn ) { - jQuery.attrFn[ name ] = true; - } - - if ( rkeyEvent.test( name ) ) { - jQuery.event.fixHooks[ name ] = jQuery.event.keyHooks; - } - - if ( rmouseEvent.test( name ) ) { - jQuery.event.fixHooks[ name ] = jQuery.event.mouseHooks; - } -}); - - - -/*! - * Sizzle CSS Selector Engine - * Copyright 2011, The Dojo Foundation - * Released under the MIT, BSD, and GPL Licenses. - * More information: http://sizzlejs.com/ - */ -(function(){ - -var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g, - expando = "sizcache" + (Math.random() + '').replace('.', ''), - done = 0, - toString = Object.prototype.toString, - hasDuplicate = false, - baseHasDuplicate = true, - rBackslash = /\\/g, - rReturn = /\r\n/g, - rNonWord = /\W/; - -// Here we check if the JavaScript engine is using some sort of -// optimization where it does not always call our comparision -// function. If that is the case, discard the hasDuplicate value. -// Thus far that includes Google Chrome. -[0, 0].sort(function() { - baseHasDuplicate = false; - return 0; -}); - -var Sizzle = function( selector, context, results, seed ) { - results = results || []; - context = context || document; - - var origContext = context; - - if ( context.nodeType !== 1 && context.nodeType !== 9 ) { - return []; - } - - if ( !selector || typeof selector !== "string" ) { - return results; - } - - var m, set, checkSet, extra, ret, cur, pop, i, - prune = true, - contextXML = Sizzle.isXML( context ), - parts = [], - soFar = selector; - - // Reset the position of the chunker regexp (start from head) - do { - chunker.exec( "" ); - m = chunker.exec( soFar ); - - if ( m ) { - soFar = m[3]; - - parts.push( m[1] ); - - if ( m[2] ) { - extra = m[3]; - break; - } - } - } while ( m ); - - if ( parts.length > 1 && origPOS.exec( selector ) ) { - - if ( parts.length === 2 && Expr.relative[ parts[0] ] ) { - set = posProcess( parts[0] + parts[1], context, seed ); - - } else { - set = Expr.relative[ parts[0] ] ? - [ context ] : - Sizzle( parts.shift(), context ); - - while ( parts.length ) { - selector = parts.shift(); - - if ( Expr.relative[ selector ] ) { - selector += parts.shift(); - } - - set = posProcess( selector, set, seed ); - } - } - - } else { - // Take a shortcut and set the context if the root selector is an ID - // (but not if it'll be faster if the inner selector is an ID) - if ( !seed && parts.length > 1 && context.nodeType === 9 && !contextXML && - Expr.match.ID.test(parts[0]) && !Expr.match.ID.test(parts[parts.length - 1]) ) { - - ret = Sizzle.find( parts.shift(), context, contextXML ); - context = ret.expr ? - Sizzle.filter( ret.expr, ret.set )[0] : - ret.set[0]; - } - - if ( context ) { - ret = seed ? - { expr: parts.pop(), set: makeArray(seed) } : - Sizzle.find( parts.pop(), parts.length === 1 && (parts[0] === "~" || parts[0] === "+") && context.parentNode ? context.parentNode : context, contextXML ); - - set = ret.expr ? - Sizzle.filter( ret.expr, ret.set ) : - ret.set; - - if ( parts.length > 0 ) { - checkSet = makeArray( set ); - - } else { - prune = false; - } - - while ( parts.length ) { - cur = parts.pop(); - pop = cur; - - if ( !Expr.relative[ cur ] ) { - cur = ""; - } else { - pop = parts.pop(); - } - - if ( pop == null ) { - pop = context; - } - - Expr.relative[ cur ]( checkSet, pop, contextXML ); - } - - } else { - checkSet = parts = []; - } - } - - if ( !checkSet ) { - checkSet = set; - } - - if ( !checkSet ) { - Sizzle.error( cur || selector ); - } - - if ( toString.call(checkSet) === "[object Array]" ) { - if ( !prune ) { - results.push.apply( results, checkSet ); - - } else if ( context && context.nodeType === 1 ) { - for ( i = 0; checkSet[i] != null; i++ ) { - if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && Sizzle.contains(context, checkSet[i])) ) { - results.push( set[i] ); - } - } - - } else { - for ( i = 0; checkSet[i] != null; i++ ) { - if ( checkSet[i] && checkSet[i].nodeType === 1 ) { - results.push( set[i] ); - } - } - } - - } else { - makeArray( checkSet, results ); - } - - if ( extra ) { - Sizzle( extra, origContext, results, seed ); - Sizzle.uniqueSort( results ); - } - - return results; -}; - -Sizzle.uniqueSort = function( results ) { - if ( sortOrder ) { - hasDuplicate = baseHasDuplicate; - results.sort( sortOrder ); - - if ( hasDuplicate ) { - for ( var i = 1; i < results.length; i++ ) { - if ( results[i] === results[ i - 1 ] ) { - results.splice( i--, 1 ); - } - } - } - } - - return results; -}; - -Sizzle.matches = function( expr, set ) { - return Sizzle( expr, null, null, set ); -}; - -Sizzle.matchesSelector = function( node, expr ) { - return Sizzle( expr, null, null, [node] ).length > 0; -}; - -Sizzle.find = function( expr, context, isXML ) { - var set, i, len, match, type, left; - - if ( !expr ) { - return []; - } - - for ( i = 0, len = Expr.order.length; i < len; i++ ) { - type = Expr.order[i]; - - if ( (match = Expr.leftMatch[ type ].exec( expr )) ) { - left = match[1]; - match.splice( 1, 1 ); - - if ( left.substr( left.length - 1 ) !== "\\" ) { - match[1] = (match[1] || "").replace( rBackslash, "" ); - set = Expr.find[ type ]( match, context, isXML ); - - if ( set != null ) { - expr = expr.replace( Expr.match[ type ], "" ); - break; - } - } - } - } - - if ( !set ) { - set = typeof context.getElementsByTagName !== "undefined" ? - context.getElementsByTagName( "*" ) : - []; - } - - return { set: set, expr: expr }; -}; - -Sizzle.filter = function( expr, set, inplace, not ) { - var match, anyFound, - type, found, item, filter, left, - i, pass, - old = expr, - result = [], - curLoop = set, - isXMLFilter = set && set[0] && Sizzle.isXML( set[0] ); - - while ( expr && set.length ) { - for ( type in Expr.filter ) { - if ( (match = Expr.leftMatch[ type ].exec( expr )) != null && match[2] ) { - filter = Expr.filter[ type ]; - left = match[1]; - - anyFound = false; - - match.splice(1,1); - - if ( left.substr( left.length - 1 ) === "\\" ) { - continue; - } - - if ( curLoop === result ) { - result = []; - } - - if ( Expr.preFilter[ type ] ) { - match = Expr.preFilter[ type ]( match, curLoop, inplace, result, not, isXMLFilter ); - - if ( !match ) { - anyFound = found = true; - - } else if ( match === true ) { - continue; - } - } - - if ( match ) { - for ( i = 0; (item = curLoop[i]) != null; i++ ) { - if ( item ) { - found = filter( item, match, i, curLoop ); - pass = not ^ found; - - if ( inplace && found != null ) { - if ( pass ) { - anyFound = true; - - } else { - curLoop[i] = false; - } - - } else if ( pass ) { - result.push( item ); - anyFound = true; - } - } - } - } - - if ( found !== undefined ) { - if ( !inplace ) { - curLoop = result; - } - - expr = expr.replace( Expr.match[ type ], "" ); - - if ( !anyFound ) { - return []; - } - - break; - } - } - } - - // Improper expression - if ( expr === old ) { - if ( anyFound == null ) { - Sizzle.error( expr ); - - } else { - break; - } - } - - old = expr; - } - - return curLoop; -}; - -Sizzle.error = function( msg ) { - throw new Error( "Syntax error, unrecognized expression: " + msg ); -}; - -/** - * Utility function for retreiving the text value of an array of DOM nodes - * @param {Array|Element} elem - */ -var getText = Sizzle.getText = function( elem ) { - var i, node, - nodeType = elem.nodeType, - ret = ""; - - if ( nodeType ) { - if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) { - // Use textContent || innerText for elements - if ( typeof elem.textContent === 'string' ) { - return elem.textContent; - } else if ( typeof elem.innerText === 'string' ) { - // Replace IE's carriage returns - return elem.innerText.replace( rReturn, '' ); - } else { - // Traverse it's children - for ( elem = elem.firstChild; elem; elem = elem.nextSibling) { - ret += getText( elem ); - } - } - } else if ( nodeType === 3 || nodeType === 4 ) { - return elem.nodeValue; - } - } else { - - // If no nodeType, this is expected to be an array - for ( i = 0; (node = elem[i]); i++ ) { - // Do not traverse comment nodes - if ( node.nodeType !== 8 ) { - ret += getText( node ); - } - } - } - return ret; -}; - -var Expr = Sizzle.selectors = { - order: [ "ID", "NAME", "TAG" ], - - match: { - ID: /#((?:[\w\u00c0-\uFFFF\-]|\\.)+)/, - CLASS: /\.((?:[\w\u00c0-\uFFFF\-]|\\.)+)/, - NAME: /\[name=['"]*((?:[\w\u00c0-\uFFFF\-]|\\.)+)['"]*\]/, - ATTR: /\[\s*((?:[\w\u00c0-\uFFFF\-]|\\.)+)\s*(?:(\S?=)\s*(?:(['"])(.*?)\3|(#?(?:[\w\u00c0-\uFFFF\-]|\\.)*)|)|)\s*\]/, - TAG: /^((?:[\w\u00c0-\uFFFF\*\-]|\\.)+)/, - CHILD: /:(only|nth|last|first)-child(?:\(\s*(even|odd|(?:[+\-]?\d+|(?:[+\-]?\d*)?n\s*(?:[+\-]\s*\d+)?))\s*\))?/, - POS: /:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^\-]|$)/, - PSEUDO: /:((?:[\w\u00c0-\uFFFF\-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/ - }, - - leftMatch: {}, - - attrMap: { - "class": "className", - "for": "htmlFor" - }, - - attrHandle: { - href: function( elem ) { - return elem.getAttribute( "href" ); - }, - type: function( elem ) { - return elem.getAttribute( "type" ); - } - }, - - relative: { - "+": function(checkSet, part){ - var isPartStr = typeof part === "string", - isTag = isPartStr && !rNonWord.test( part ), - isPartStrNotTag = isPartStr && !isTag; - - if ( isTag ) { - part = part.toLowerCase(); - } - - for ( var i = 0, l = checkSet.length, elem; i < l; i++ ) { - if ( (elem = checkSet[i]) ) { - while ( (elem = elem.previousSibling) && elem.nodeType !== 1 ) {} - - checkSet[i] = isPartStrNotTag || elem && elem.nodeName.toLowerCase() === part ? - elem || false : - elem === part; - } - } - - if ( isPartStrNotTag ) { - Sizzle.filter( part, checkSet, true ); - } - }, - - ">": function( checkSet, part ) { - var elem, - isPartStr = typeof part === "string", - i = 0, - l = checkSet.length; - - if ( isPartStr && !rNonWord.test( part ) ) { - part = part.toLowerCase(); - - for ( ; i < l; i++ ) { - elem = checkSet[i]; - - if ( elem ) { - var parent = elem.parentNode; - checkSet[i] = parent.nodeName.toLowerCase() === part ? parent : false; - } - } - - } else { - for ( ; i < l; i++ ) { - elem = checkSet[i]; - - if ( elem ) { - checkSet[i] = isPartStr ? - elem.parentNode : - elem.parentNode === part; - } - } - - if ( isPartStr ) { - Sizzle.filter( part, checkSet, true ); - } - } - }, - - "": function(checkSet, part, isXML){ - var nodeCheck, - doneName = done++, - checkFn = dirCheck; - - if ( typeof part === "string" && !rNonWord.test( part ) ) { - part = part.toLowerCase(); - nodeCheck = part; - checkFn = dirNodeCheck; - } - - checkFn( "parentNode", part, doneName, checkSet, nodeCheck, isXML ); - }, - - "~": function( checkSet, part, isXML ) { - var nodeCheck, - doneName = done++, - checkFn = dirCheck; - - if ( typeof part === "string" && !rNonWord.test( part ) ) { - part = part.toLowerCase(); - nodeCheck = part; - checkFn = dirNodeCheck; - } - - checkFn( "previousSibling", part, doneName, checkSet, nodeCheck, isXML ); - } - }, - - find: { - ID: function( match, context, isXML ) { - if ( typeof context.getElementById !== "undefined" && !isXML ) { - var m = context.getElementById(match[1]); - // Check parentNode to catch when Blackberry 4.6 returns - // nodes that are no longer in the document #6963 - return m && m.parentNode ? [m] : []; - } - }, - - NAME: function( match, context ) { - if ( typeof context.getElementsByName !== "undefined" ) { - var ret = [], - results = context.getElementsByName( match[1] ); - - for ( var i = 0, l = results.length; i < l; i++ ) { - if ( results[i].getAttribute("name") === match[1] ) { - ret.push( results[i] ); - } - } - - return ret.length === 0 ? null : ret; - } - }, - - TAG: function( match, context ) { - if ( typeof context.getElementsByTagName !== "undefined" ) { - return context.getElementsByTagName( match[1] ); - } - } - }, - preFilter: { - CLASS: function( match, curLoop, inplace, result, not, isXML ) { - match = " " + match[1].replace( rBackslash, "" ) + " "; - - if ( isXML ) { - return match; - } - - for ( var i = 0, elem; (elem = curLoop[i]) != null; i++ ) { - if ( elem ) { - if ( not ^ (elem.className && (" " + elem.className + " ").replace(/[\t\n\r]/g, " ").indexOf(match) >= 0) ) { - if ( !inplace ) { - result.push( elem ); - } - - } else if ( inplace ) { - curLoop[i] = false; - } - } - } - - return false; - }, - - ID: function( match ) { - return match[1].replace( rBackslash, "" ); - }, - - TAG: function( match, curLoop ) { - return match[1].replace( rBackslash, "" ).toLowerCase(); - }, - - CHILD: function( match ) { - if ( match[1] === "nth" ) { - if ( !match[2] ) { - Sizzle.error( match[0] ); - } - - match[2] = match[2].replace(/^\+|\s*/g, ''); - - // parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6' - var test = /(-?)(\d*)(?:n([+\-]?\d*))?/.exec( - match[2] === "even" && "2n" || match[2] === "odd" && "2n+1" || - !/\D/.test( match[2] ) && "0n+" + match[2] || match[2]); - - // calculate the numbers (first)n+(last) including if they are negative - match[2] = (test[1] + (test[2] || 1)) - 0; - match[3] = test[3] - 0; - } - else if ( match[2] ) { - Sizzle.error( match[0] ); - } - - // TODO: Move to normal caching system - match[0] = done++; - - return match; - }, - - ATTR: function( match, curLoop, inplace, result, not, isXML ) { - var name = match[1] = match[1].replace( rBackslash, "" ); - - if ( !isXML && Expr.attrMap[name] ) { - match[1] = Expr.attrMap[name]; - } - - // Handle if an un-quoted value was used - match[4] = ( match[4] || match[5] || "" ).replace( rBackslash, "" ); - - if ( match[2] === "~=" ) { - match[4] = " " + match[4] + " "; - } - - return match; - }, - - PSEUDO: function( match, curLoop, inplace, result, not ) { - if ( match[1] === "not" ) { - // If we're dealing with a complex expression, or a simple one - if ( ( chunker.exec(match[3]) || "" ).length > 1 || /^\w/.test(match[3]) ) { - match[3] = Sizzle(match[3], null, null, curLoop); - - } else { - var ret = Sizzle.filter(match[3], curLoop, inplace, true ^ not); - - if ( !inplace ) { - result.push.apply( result, ret ); - } - - return false; - } - - } else if ( Expr.match.POS.test( match[0] ) || Expr.match.CHILD.test( match[0] ) ) { - return true; - } - - return match; - }, - - POS: function( match ) { - match.unshift( true ); - - return match; - } - }, - - filters: { - enabled: function( elem ) { - return elem.disabled === false && elem.type !== "hidden"; - }, - - disabled: function( elem ) { - return elem.disabled === true; - }, - - checked: function( elem ) { - return elem.checked === true; - }, - - selected: function( elem ) { - // Accessing this property makes selected-by-default - // options in Safari work properly - if ( elem.parentNode ) { - elem.parentNode.selectedIndex; - } - - return elem.selected === true; - }, - - parent: function( elem ) { - return !!elem.firstChild; - }, - - empty: function( elem ) { - return !elem.firstChild; - }, - - has: function( elem, i, match ) { - return !!Sizzle( match[3], elem ).length; - }, - - header: function( elem ) { - return (/h\d/i).test( elem.nodeName ); - }, - - text: function( elem ) { - var attr = elem.getAttribute( "type" ), type = elem.type; - // IE6 and 7 will map elem.type to 'text' for new HTML5 types (search, etc) - // use getAttribute instead to test this case - return elem.nodeName.toLowerCase() === "input" && "text" === type && ( attr === type || attr === null ); - }, - - radio: function( elem ) { - return elem.nodeName.toLowerCase() === "input" && "radio" === elem.type; - }, - - checkbox: function( elem ) { - return elem.nodeName.toLowerCase() === "input" && "checkbox" === elem.type; - }, - - file: function( elem ) { - return elem.nodeName.toLowerCase() === "input" && "file" === elem.type; - }, - - password: function( elem ) { - return elem.nodeName.toLowerCase() === "input" && "password" === elem.type; - }, - - submit: function( elem ) { - var name = elem.nodeName.toLowerCase(); - return (name === "input" || name === "button") && "submit" === elem.type; - }, - - image: function( elem ) { - return elem.nodeName.toLowerCase() === "input" && "image" === elem.type; - }, - - reset: function( elem ) { - var name = elem.nodeName.toLowerCase(); - return (name === "input" || name === "button") && "reset" === elem.type; - }, - - button: function( elem ) { - var name = elem.nodeName.toLowerCase(); - return name === "input" && "button" === elem.type || name === "button"; - }, - - input: function( elem ) { - return (/input|select|textarea|button/i).test( elem.nodeName ); - }, - - focus: function( elem ) { - return elem === elem.ownerDocument.activeElement; - } - }, - setFilters: { - first: function( elem, i ) { - return i === 0; - }, - - last: function( elem, i, match, array ) { - return i === array.length - 1; - }, - - even: function( elem, i ) { - return i % 2 === 0; - }, - - odd: function( elem, i ) { - return i % 2 === 1; - }, - - lt: function( elem, i, match ) { - return i < match[3] - 0; - }, - - gt: function( elem, i, match ) { - return i > match[3] - 0; - }, - - nth: function( elem, i, match ) { - return match[3] - 0 === i; - }, - - eq: function( elem, i, match ) { - return match[3] - 0 === i; - } - }, - filter: { - PSEUDO: function( elem, match, i, array ) { - var name = match[1], - filter = Expr.filters[ name ]; - - if ( filter ) { - return filter( elem, i, match, array ); - - } else if ( name === "contains" ) { - return (elem.textContent || elem.innerText || getText([ elem ]) || "").indexOf(match[3]) >= 0; - - } else if ( name === "not" ) { - var not = match[3]; - - for ( var j = 0, l = not.length; j < l; j++ ) { - if ( not[j] === elem ) { - return false; - } - } - - return true; - - } else { - Sizzle.error( name ); - } - }, - - CHILD: function( elem, match ) { - var first, last, - doneName, parent, cache, - count, diff, - type = match[1], - node = elem; - - switch ( type ) { - case "only": - case "first": - while ( (node = node.previousSibling) ) { - if ( node.nodeType === 1 ) { - return false; - } - } - - if ( type === "first" ) { - return true; - } - - node = elem; - - /* falls through */ - case "last": - while ( (node = node.nextSibling) ) { - if ( node.nodeType === 1 ) { - return false; - } - } - - return true; - - case "nth": - first = match[2]; - last = match[3]; - - if ( first === 1 && last === 0 ) { - return true; - } - - doneName = match[0]; - parent = elem.parentNode; - - if ( parent && (parent[ expando ] !== doneName || !elem.nodeIndex) ) { - count = 0; - - for ( node = parent.firstChild; node; node = node.nextSibling ) { - if ( node.nodeType === 1 ) { - node.nodeIndex = ++count; - } - } - - parent[ expando ] = doneName; - } - - diff = elem.nodeIndex - last; - - if ( first === 0 ) { - return diff === 0; - - } else { - return ( diff % first === 0 && diff / first >= 0 ); - } - } - }, - - ID: function( elem, match ) { - return elem.nodeType === 1 && elem.getAttribute("id") === match; - }, - - TAG: function( elem, match ) { - return (match === "*" && elem.nodeType === 1) || !!elem.nodeName && elem.nodeName.toLowerCase() === match; - }, - - CLASS: function( elem, match ) { - return (" " + (elem.className || elem.getAttribute("class")) + " ") - .indexOf( match ) > -1; - }, - - ATTR: function( elem, match ) { - var name = match[1], - result = Sizzle.attr ? - Sizzle.attr( elem, name ) : - Expr.attrHandle[ name ] ? - Expr.attrHandle[ name ]( elem ) : - elem[ name ] != null ? - elem[ name ] : - elem.getAttribute( name ), - value = result + "", - type = match[2], - check = match[4]; - - return result == null ? - type === "!=" : - !type && Sizzle.attr ? - result != null : - type === "=" ? - value === check : - type === "*=" ? - value.indexOf(check) >= 0 : - type === "~=" ? - (" " + value + " ").indexOf(check) >= 0 : - !check ? - value && result !== false : - type === "!=" ? - value !== check : - type === "^=" ? - value.indexOf(check) === 0 : - type === "$=" ? - value.substr(value.length - check.length) === check : - type === "|=" ? - value === check || value.substr(0, check.length + 1) === check + "-" : - false; - }, - - POS: function( elem, match, i, array ) { - var name = match[2], - filter = Expr.setFilters[ name ]; - - if ( filter ) { - return filter( elem, i, match, array ); - } - } - } -}; - -var origPOS = Expr.match.POS, - fescape = function(all, num){ - return "\\" + (num - 0 + 1); - }; - -for ( var type in Expr.match ) { - Expr.match[ type ] = new RegExp( Expr.match[ type ].source + (/(?![^\[]*\])(?![^\(]*\))/.source) ); - Expr.leftMatch[ type ] = new RegExp( /(^(?:.|\r|\n)*?)/.source + Expr.match[ type ].source.replace(/\\(\d+)/g, fescape) ); -} -// Expose origPOS -// "global" as in regardless of relation to brackets/parens -Expr.match.globalPOS = origPOS; - -var makeArray = function( array, results ) { - array = Array.prototype.slice.call( array, 0 ); - - if ( results ) { - results.push.apply( results, array ); - return results; - } - - return array; -}; - -// Perform a simple check to determine if the browser is capable of -// converting a NodeList to an array using builtin methods. -// Also verifies that the returned array holds DOM nodes -// (which is not the case in the Blackberry browser) -try { - Array.prototype.slice.call( document.documentElement.childNodes, 0 )[0].nodeType; - -// Provide a fallback method if it does not work -} catch( e ) { - makeArray = function( array, results ) { - var i = 0, - ret = results || []; - - if ( toString.call(array) === "[object Array]" ) { - Array.prototype.push.apply( ret, array ); - - } else { - if ( typeof array.length === "number" ) { - for ( var l = array.length; i < l; i++ ) { - ret.push( array[i] ); - } - - } else { - for ( ; array[i]; i++ ) { - ret.push( array[i] ); - } - } - } - - return ret; - }; -} - -var sortOrder, siblingCheck; - -if ( document.documentElement.compareDocumentPosition ) { - sortOrder = function( a, b ) { - if ( a === b ) { - hasDuplicate = true; - return 0; - } - - if ( !a.compareDocumentPosition || !b.compareDocumentPosition ) { - return a.compareDocumentPosition ? -1 : 1; - } - - return a.compareDocumentPosition(b) & 4 ? -1 : 1; - }; - -} else { - sortOrder = function( a, b ) { - // The nodes are identical, we can exit early - if ( a === b ) { - hasDuplicate = true; - return 0; - - // Fallback to using sourceIndex (in IE) if it's available on both nodes - } else if ( a.sourceIndex && b.sourceIndex ) { - return a.sourceIndex - b.sourceIndex; - } - - var al, bl, - ap = [], - bp = [], - aup = a.parentNode, - bup = b.parentNode, - cur = aup; - - // If the nodes are siblings (or identical) we can do a quick check - if ( aup === bup ) { - return siblingCheck( a, b ); - - // If no parents were found then the nodes are disconnected - } else if ( !aup ) { - return -1; - - } else if ( !bup ) { - return 1; - } - - // Otherwise they're somewhere else in the tree so we need - // to build up a full list of the parentNodes for comparison - while ( cur ) { - ap.unshift( cur ); - cur = cur.parentNode; - } - - cur = bup; - - while ( cur ) { - bp.unshift( cur ); - cur = cur.parentNode; - } - - al = ap.length; - bl = bp.length; - - // Start walking down the tree looking for a discrepancy - for ( var i = 0; i < al && i < bl; i++ ) { - if ( ap[i] !== bp[i] ) { - return siblingCheck( ap[i], bp[i] ); - } - } - - // We ended someplace up the tree so do a sibling check - return i === al ? - siblingCheck( a, bp[i], -1 ) : - siblingCheck( ap[i], b, 1 ); - }; - - siblingCheck = function( a, b, ret ) { - if ( a === b ) { - return ret; - } - - var cur = a.nextSibling; - - while ( cur ) { - if ( cur === b ) { - return -1; - } - - cur = cur.nextSibling; - } - - return 1; - }; -} - -// Check to see if the browser returns elements by name when -// querying by getElementById (and provide a workaround) -(function(){ - // We're going to inject a fake input element with a specified name - var form = document.createElement("div"), - id = "script" + (new Date()).getTime(), - root = document.documentElement; - - form.innerHTML = ""; - - // Inject it into the root element, check its status, and remove it quickly - root.insertBefore( form, root.firstChild ); - - // The workaround has to do additional checks after a getElementById - // Which slows things down for other browsers (hence the branching) - if ( document.getElementById( id ) ) { - Expr.find.ID = function( match, context, isXML ) { - if ( typeof context.getElementById !== "undefined" && !isXML ) { - var m = context.getElementById(match[1]); - - return m ? - m.id === match[1] || typeof m.getAttributeNode !== "undefined" && m.getAttributeNode("id").nodeValue === match[1] ? - [m] : - undefined : - []; - } - }; - - Expr.filter.ID = function( elem, match ) { - var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id"); - - return elem.nodeType === 1 && node && node.nodeValue === match; - }; - } - - root.removeChild( form ); - - // release memory in IE - root = form = null; -})(); - -(function(){ - // Check to see if the browser returns only elements - // when doing getElementsByTagName("*") - - // Create a fake element - var div = document.createElement("div"); - div.appendChild( document.createComment("") ); - - // Make sure no comments are found - if ( div.getElementsByTagName("*").length > 0 ) { - Expr.find.TAG = function( match, context ) { - var results = context.getElementsByTagName( match[1] ); - - // Filter out possible comments - if ( match[1] === "*" ) { - var tmp = []; - - for ( var i = 0; results[i]; i++ ) { - if ( results[i].nodeType === 1 ) { - tmp.push( results[i] ); - } - } - - results = tmp; - } - - return results; - }; - } - - // Check to see if an attribute returns normalized href attributes - div.innerHTML = ""; - - if ( div.firstChild && typeof div.firstChild.getAttribute !== "undefined" && - div.firstChild.getAttribute("href") !== "#" ) { - - Expr.attrHandle.href = function( elem ) { - return elem.getAttribute( "href", 2 ); - }; - } - - // release memory in IE - div = null; -})(); - -if ( document.querySelectorAll ) { - (function(){ - var oldSizzle = Sizzle, - div = document.createElement("div"), - id = "__sizzle__"; - - div.innerHTML = "

"; - - // Safari can't handle uppercase or unicode characters when - // in quirks mode. - if ( div.querySelectorAll && div.querySelectorAll(".TEST").length === 0 ) { - return; - } - - Sizzle = function( query, context, extra, seed ) { - context = context || document; - - // Only use querySelectorAll on non-XML documents - // (ID selectors don't work in non-HTML documents) - if ( !seed && !Sizzle.isXML(context) ) { - // See if we find a selector to speed up - var match = /^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec( query ); - - if ( match && (context.nodeType === 1 || context.nodeType === 9) ) { - // Speed-up: Sizzle("TAG") - if ( match[1] ) { - return makeArray( context.getElementsByTagName( query ), extra ); - - // Speed-up: Sizzle(".CLASS") - } else if ( match[2] && Expr.find.CLASS && context.getElementsByClassName ) { - return makeArray( context.getElementsByClassName( match[2] ), extra ); - } - } - - if ( context.nodeType === 9 ) { - // Speed-up: Sizzle("body") - // The body element only exists once, optimize finding it - if ( query === "body" && context.body ) { - return makeArray( [ context.body ], extra ); - - // Speed-up: Sizzle("#ID") - } else if ( match && match[3] ) { - var elem = context.getElementById( match[3] ); - - // Check parentNode to catch when Blackberry 4.6 returns - // nodes that are no longer in the document #6963 - if ( elem && elem.parentNode ) { - // Handle the case where IE and Opera return items - // by name instead of ID - if ( elem.id === match[3] ) { - return makeArray( [ elem ], extra ); - } - - } else { - return makeArray( [], extra ); - } - } - - try { - return makeArray( context.querySelectorAll(query), extra ); - } catch(qsaError) {} - - // qSA works strangely on Element-rooted queries - // We can work around this by specifying an extra ID on the root - // and working up from there (Thanks to Andrew Dupont for the technique) - // IE 8 doesn't work on object elements - } else if ( context.nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) { - var oldContext = context, - old = context.getAttribute( "id" ), - nid = old || id, - hasParent = context.parentNode, - relativeHierarchySelector = /^\s*[+~]/.test( query ); - - if ( !old ) { - context.setAttribute( "id", nid ); - } else { - nid = nid.replace( /'/g, "\\$&" ); - } - if ( relativeHierarchySelector && hasParent ) { - context = context.parentNode; - } - - try { - if ( !relativeHierarchySelector || hasParent ) { - return makeArray( context.querySelectorAll( "[id='" + nid + "'] " + query ), extra ); - } - - } catch(pseudoError) { - } finally { - if ( !old ) { - oldContext.removeAttribute( "id" ); - } - } - } - } - - return oldSizzle(query, context, extra, seed); - }; - - for ( var prop in oldSizzle ) { - Sizzle[ prop ] = oldSizzle[ prop ]; - } - - // release memory in IE - div = null; - })(); -} - -(function(){ - var html = document.documentElement, - matches = html.matchesSelector || html.mozMatchesSelector || html.webkitMatchesSelector || html.msMatchesSelector; - - if ( matches ) { - // Check to see if it's possible to do matchesSelector - // on a disconnected node (IE 9 fails this) - var disconnectedMatch = !matches.call( document.createElement( "div" ), "div" ), - pseudoWorks = false; - - try { - // This should fail with an exception - // Gecko does not error, returns false instead - matches.call( document.documentElement, "[test!='']:sizzle" ); - - } catch( pseudoError ) { - pseudoWorks = true; - } - - Sizzle.matchesSelector = function( node, expr ) { - // Make sure that attribute selectors are quoted - expr = expr.replace(/\=\s*([^'"\]]*)\s*\]/g, "='$1']"); - - if ( !Sizzle.isXML( node ) ) { - try { - if ( pseudoWorks || !Expr.match.PSEUDO.test( expr ) && !/!=/.test( expr ) ) { - var ret = matches.call( node, expr ); - - // IE 9's matchesSelector returns false on disconnected nodes - if ( ret || !disconnectedMatch || - // As well, disconnected nodes are said to be in a document - // fragment in IE 9, so check for that - node.document && node.document.nodeType !== 11 ) { - return ret; - } - } - } catch(e) {} - } - - return Sizzle(expr, null, null, [node]).length > 0; - }; - } -})(); - -(function(){ - var div = document.createElement("div"); - - div.innerHTML = "
"; - - // Opera can't find a second classname (in 9.6) - // Also, make sure that getElementsByClassName actually exists - if ( !div.getElementsByClassName || div.getElementsByClassName("e").length === 0 ) { - return; - } - - // Safari caches class attributes, doesn't catch changes (in 3.2) - div.lastChild.className = "e"; - - if ( div.getElementsByClassName("e").length === 1 ) { - return; - } - - Expr.order.splice(1, 0, "CLASS"); - Expr.find.CLASS = function( match, context, isXML ) { - if ( typeof context.getElementsByClassName !== "undefined" && !isXML ) { - return context.getElementsByClassName(match[1]); - } - }; - - // release memory in IE - div = null; -})(); - -function dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) { - for ( var i = 0, l = checkSet.length; i < l; i++ ) { - var elem = checkSet[i]; - - if ( elem ) { - var match = false; - - elem = elem[dir]; - - while ( elem ) { - if ( elem[ expando ] === doneName ) { - match = checkSet[elem.sizset]; - break; - } - - if ( elem.nodeType === 1 && !isXML ){ - elem[ expando ] = doneName; - elem.sizset = i; - } - - if ( elem.nodeName.toLowerCase() === cur ) { - match = elem; - break; - } - - elem = elem[dir]; - } - - checkSet[i] = match; - } - } -} - -function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) { - for ( var i = 0, l = checkSet.length; i < l; i++ ) { - var elem = checkSet[i]; - - if ( elem ) { - var match = false; - - elem = elem[dir]; - - while ( elem ) { - if ( elem[ expando ] === doneName ) { - match = checkSet[elem.sizset]; - break; - } - - if ( elem.nodeType === 1 ) { - if ( !isXML ) { - elem[ expando ] = doneName; - elem.sizset = i; - } - - if ( typeof cur !== "string" ) { - if ( elem === cur ) { - match = true; - break; - } - - } else if ( Sizzle.filter( cur, [elem] ).length > 0 ) { - match = elem; - break; - } - } - - elem = elem[dir]; - } - - checkSet[i] = match; - } - } -} - -if ( document.documentElement.contains ) { - Sizzle.contains = function( a, b ) { - return a !== b && (a.contains ? a.contains(b) : true); - }; - -} else if ( document.documentElement.compareDocumentPosition ) { - Sizzle.contains = function( a, b ) { - return !!(a.compareDocumentPosition(b) & 16); - }; - -} else { - Sizzle.contains = function() { - return false; - }; -} - -Sizzle.isXML = function( elem ) { - // documentElement is verified for cases where it doesn't yet exist - // (such as loading iframes in IE - #4833) - var documentElement = (elem ? elem.ownerDocument || elem : 0).documentElement; - - return documentElement ? documentElement.nodeName !== "HTML" : false; -}; - -var posProcess = function( selector, context, seed ) { - var match, - tmpSet = [], - later = "", - root = context.nodeType ? [context] : context; - - // Position selectors must be done after the filter - // And so must :not(positional) so we move all PSEUDOs to the end - while ( (match = Expr.match.PSEUDO.exec( selector )) ) { - later += match[0]; - selector = selector.replace( Expr.match.PSEUDO, "" ); - } - - selector = Expr.relative[selector] ? selector + "*" : selector; - - for ( var i = 0, l = root.length; i < l; i++ ) { - Sizzle( selector, root[i], tmpSet, seed ); - } - - return Sizzle.filter( later, tmpSet ); -}; - -// EXPOSE -// Override sizzle attribute retrieval -Sizzle.attr = jQuery.attr; -Sizzle.selectors.attrMap = {}; -jQuery.find = Sizzle; -jQuery.expr = Sizzle.selectors; -jQuery.expr[":"] = jQuery.expr.filters; -jQuery.unique = Sizzle.uniqueSort; -jQuery.text = Sizzle.getText; -jQuery.isXMLDoc = Sizzle.isXML; -jQuery.contains = Sizzle.contains; - - -})(); - - -var runtil = /Until$/, - rparentsprev = /^(?:parents|prevUntil|prevAll)/, - // Note: This RegExp should be improved, or likely pulled from Sizzle - rmultiselector = /,/, - isSimple = /^.[^:#\[\.,]*$/, - slice = Array.prototype.slice, - POS = jQuery.expr.match.globalPOS, - // methods guaranteed to produce a unique set when starting from a unique set - guaranteedUnique = { - children: true, - contents: true, - next: true, - prev: true - }; - -jQuery.fn.extend({ - find: function( selector ) { - var self = this, - i, l; - - if ( typeof selector !== "string" ) { - return jQuery( selector ).filter(function() { - for ( i = 0, l = self.length; i < l; i++ ) { - if ( jQuery.contains( self[ i ], this ) ) { - return true; - } - } - }); - } - - var ret = this.pushStack( "", "find", selector ), - length, n, r; - - for ( i = 0, l = this.length; i < l; i++ ) { - length = ret.length; - jQuery.find( selector, this[i], ret ); - - if ( i > 0 ) { - // Make sure that the results are unique - for ( n = length; n < ret.length; n++ ) { - for ( r = 0; r < length; r++ ) { - if ( ret[r] === ret[n] ) { - ret.splice(n--, 1); - break; - } - } - } - } - } - - return ret; - }, - - has: function( target ) { - var targets = jQuery( target ); - return this.filter(function() { - for ( var i = 0, l = targets.length; i < l; i++ ) { - if ( jQuery.contains( this, targets[i] ) ) { - return true; - } - } - }); - }, - - not: function( selector ) { - return this.pushStack( winnow(this, selector, false), "not", selector); - }, - - filter: function( selector ) { - return this.pushStack( winnow(this, selector, true), "filter", selector ); - }, - - is: function( selector ) { - return !!selector && ( - typeof selector === "string" ? - // If this is a positional selector, check membership in the returned set - // so $("p:first").is("p:last") won't return true for a doc with two "p". - POS.test( selector ) ? - jQuery( selector, this.context ).index( this[0] ) >= 0 : - jQuery.filter( selector, this ).length > 0 : - this.filter( selector ).length > 0 ); - }, - - closest: function( selectors, context ) { - var ret = [], i, l, cur = this[0]; - - // Array (deprecated as of jQuery 1.7) - if ( jQuery.isArray( selectors ) ) { - var level = 1; - - while ( cur && cur.ownerDocument && cur !== context ) { - for ( i = 0; i < selectors.length; i++ ) { - - if ( jQuery( cur ).is( selectors[ i ] ) ) { - ret.push({ selector: selectors[ i ], elem: cur, level: level }); - } - } - - cur = cur.parentNode; - level++; - } - - return ret; - } - - // String - var pos = POS.test( selectors ) || typeof selectors !== "string" ? - jQuery( selectors, context || this.context ) : - 0; - - for ( i = 0, l = this.length; i < l; i++ ) { - cur = this[i]; - - while ( cur ) { - if ( pos ? pos.index(cur) > -1 : jQuery.find.matchesSelector(cur, selectors) ) { - ret.push( cur ); - break; - - } else { - cur = cur.parentNode; - if ( !cur || !cur.ownerDocument || cur === context || cur.nodeType === 11 ) { - break; - } - } - } - } - - ret = ret.length > 1 ? jQuery.unique( ret ) : ret; - - return this.pushStack( ret, "closest", selectors ); - }, - - // Determine the position of an element within - // the matched set of elements - index: function( elem ) { - - // No argument, return index in parent - if ( !elem ) { - return ( this[0] && this[0].parentNode ) ? this.prevAll().length : -1; - } - - // index in selector - if ( typeof elem === "string" ) { - return jQuery.inArray( this[0], jQuery( elem ) ); - } - - // Locate the position of the desired element - return jQuery.inArray( - // If it receives a jQuery object, the first element is used - elem.jquery ? elem[0] : elem, this ); - }, - - add: function( selector, context ) { - var set = typeof selector === "string" ? - jQuery( selector, context ) : - jQuery.makeArray( selector && selector.nodeType ? [ selector ] : selector ), - all = jQuery.merge( this.get(), set ); - - return this.pushStack( isDisconnected( set[0] ) || isDisconnected( all[0] ) ? - all : - jQuery.unique( all ) ); - }, - - andSelf: function() { - return this.add( this.prevObject ); - } -}); - -// A painfully simple check to see if an element is disconnected -// from a document (should be improved, where feasible). -function isDisconnected( node ) { - return !node || !node.parentNode || node.parentNode.nodeType === 11; -} - -jQuery.each({ - parent: function( elem ) { - var parent = elem.parentNode; - return parent && parent.nodeType !== 11 ? parent : null; - }, - parents: function( elem ) { - return jQuery.dir( elem, "parentNode" ); - }, - parentsUntil: function( elem, i, until ) { - return jQuery.dir( elem, "parentNode", until ); - }, - next: function( elem ) { - return jQuery.nth( elem, 2, "nextSibling" ); - }, - prev: function( elem ) { - return jQuery.nth( elem, 2, "previousSibling" ); - }, - nextAll: function( elem ) { - return jQuery.dir( elem, "nextSibling" ); - }, - prevAll: function( elem ) { - return jQuery.dir( elem, "previousSibling" ); - }, - nextUntil: function( elem, i, until ) { - return jQuery.dir( elem, "nextSibling", until ); - }, - prevUntil: function( elem, i, until ) { - return jQuery.dir( elem, "previousSibling", until ); - }, - siblings: function( elem ) { - return jQuery.sibling( ( elem.parentNode || {} ).firstChild, elem ); - }, - children: function( elem ) { - return jQuery.sibling( elem.firstChild ); - }, - contents: function( elem ) { - return jQuery.nodeName( elem, "iframe" ) ? - elem.contentDocument || elem.contentWindow.document : - jQuery.makeArray( elem.childNodes ); - } -}, function( name, fn ) { - jQuery.fn[ name ] = function( until, selector ) { - var ret = jQuery.map( this, fn, until ); - - if ( !runtil.test( name ) ) { - selector = until; - } - - if ( selector && typeof selector === "string" ) { - ret = jQuery.filter( selector, ret ); - } - - ret = this.length > 1 && !guaranteedUnique[ name ] ? jQuery.unique( ret ) : ret; - - if ( (this.length > 1 || rmultiselector.test( selector )) && rparentsprev.test( name ) ) { - ret = ret.reverse(); - } - - return this.pushStack( ret, name, slice.call( arguments ).join(",") ); - }; -}); - -jQuery.extend({ - filter: function( expr, elems, not ) { - if ( not ) { - expr = ":not(" + expr + ")"; - } - - return elems.length === 1 ? - jQuery.find.matchesSelector(elems[0], expr) ? [ elems[0] ] : [] : - jQuery.find.matches(expr, elems); - }, - - dir: function( elem, dir, until ) { - var matched = [], - cur = elem[ dir ]; - - while ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) { - if ( cur.nodeType === 1 ) { - matched.push( cur ); - } - cur = cur[dir]; - } - return matched; - }, - - nth: function( cur, result, dir, elem ) { - result = result || 1; - var num = 0; - - for ( ; cur; cur = cur[dir] ) { - if ( cur.nodeType === 1 && ++num === result ) { - break; - } - } - - return cur; - }, - - sibling: function( n, elem ) { - var r = []; - - for ( ; n; n = n.nextSibling ) { - if ( n.nodeType === 1 && n !== elem ) { - r.push( n ); - } - } - - return r; - } -}); - -// Implement the identical functionality for filter and not -function winnow( elements, qualifier, keep ) { - - // Can't pass null or undefined to indexOf in Firefox 4 - // Set to 0 to skip string check - qualifier = qualifier || 0; - - if ( jQuery.isFunction( qualifier ) ) { - return jQuery.grep(elements, function( elem, i ) { - var retVal = !!qualifier.call( elem, i, elem ); - return retVal === keep; - }); - - } else if ( qualifier.nodeType ) { - return jQuery.grep(elements, function( elem, i ) { - return ( elem === qualifier ) === keep; - }); - - } else if ( typeof qualifier === "string" ) { - var filtered = jQuery.grep(elements, function( elem ) { - return elem.nodeType === 1; - }); - - if ( isSimple.test( qualifier ) ) { - return jQuery.filter(qualifier, filtered, !keep); - } else { - qualifier = jQuery.filter( qualifier, filtered ); - } - } - - return jQuery.grep(elements, function( elem, i ) { - return ( jQuery.inArray( elem, qualifier ) >= 0 ) === keep; - }); -} - - - - -function createSafeFragment( document ) { - var list = nodeNames.split( "|" ), - safeFrag = document.createDocumentFragment(); - - if ( safeFrag.createElement ) { - while ( list.length ) { - safeFrag.createElement( - list.pop() - ); - } - } - return safeFrag; -} - -var nodeNames = "abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|" + - "header|hgroup|mark|meter|nav|output|progress|section|summary|time|video", - rinlinejQuery = / jQuery\d+="(?:\d+|null)"/g, - rleadingWhitespace = /^\s+/, - rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig, - rtagName = /<([\w:]+)/, - rtbody = /]", "i"), - // checked="checked" or checked - rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i, - rscriptType = /\/(java|ecma)script/i, - rcleanScript = /^\s*", "" ], - legend: [ 1, "
", "
" ], - thead: [ 1, "", "
" ], - tr: [ 2, "", "
" ], - td: [ 3, "", "
" ], - col: [ 2, "", "
" ], - area: [ 1, "", "" ], - _default: [ 0, "", "" ] - }, - safeFragment = createSafeFragment( document ); - -wrapMap.optgroup = wrapMap.option; -wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; -wrapMap.th = wrapMap.td; - -// IE can't serialize and - - - - - - - - -
-
-
-
- - -

Index

- -
- -
- - -
-
-
-
-
- - - - - -
-
-
-
- - - - \ No newline at end of file diff --git a/docs/_build/html/glances-doc.html b/docs/_build/html/glances-doc.html deleted file mode 100644 index f6686717..00000000 --- a/docs/_build/html/glances-doc.html +++ /dev/null @@ -1,665 +0,0 @@ - - - - - - - - - - Glances — Glances 1.7.3 documentation - - - - - - - - - - - - - - -
-
-
-
- -
-

Glances

-

This manual describes Glances version 1.7.3.

-

Copyright © 2012-2013 Nicolas Hennion <nicolas@nicolargo.com>

-

November 2013

- -
-

Introduction

-

Glances is a cross-platform curses-based monitoring tool which aims to -present a maximum of information in a minimum of space, ideally to fit -in a classical 80x24 terminal or higher to have additional information.

-

Glances can adapt dynamically the displayed information depending on the -terminal size. It can also work in a client/server mode for remote monitoring.

-

Glances is written in Python and uses the psutil library to get information from your system.

-

Console (80x24)

-_images/screenshot.png -

Full view (>80x24)

-_images/screenshot-wide.png -
-
-

Usage

-
-

Standalone mode

-

Simply run:

-
$ glances
-
-
-
-
-

Client/Server mode

-

If you want to remotely monitor a machine, called server, from another one, called client, -just run on the server:

-
server$ glances -s
-
-
-

and on the client:

-
client$ glances -c @server
-
-
-

where @server is the IP address or hostname of the server.

-

In server mode, you can set the bind address -B ADDRESS and listening TCP port -p PORT.

-

In client mode, you can set the TCP port of the server -p PORT.

-

Default binding address is 0.0.0.0 (Glances will listen on all the network interfaces) and TCP port is 61209.

-

In client/server mode, limits are set by the server side.

-

You can also set a password to access to the server -P password.

-

Glances is IPv6 compatible. Just use the -B :: option to bind to all IPv6 addresses.

-
-
-
-

Command reference

-
-

Command-line options

- --- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--bDisplay network rate in Byte per second (default: bit per second)
--B IPBind server to the given IPv4/IPv6 address or hostname
--c IPConnect to a Glances server by IPv4/IPv6 address or hostname
--C FILEPath to the configuration file
--dDisable disk I/O module
--eEnable sensors module (requires pysensors, Linux-only)
--f FILESet the HTML output folder or CSV file
--hDisplay the help and exit
--mDisable mount module
--nDisable network module
--o OUTPUTDefine additional output (available: HTML or CSV)
--p PORTDefine the client/server TCP port (default: 61209)
--P PASSWORDDefine a client/server password
---passwordDefine a client/server password from the prompt
--rDisable process list (for low CPU consumption)
--sRun Glances in server mode
--t SECONDSSet refresh time in seconds (default: 3 sec)
--vDisplay the version and exit
--yEnable hddtemp module (requires hddtemp)
--zDo not use the bold color attribute
--1Start Glances in per-CPU mode
-
-
-

Interactive commands

-

The following commands (key pressed) are supported while in Glances:

-
-
a
-

Sort process list automatically

-
    -
  • If CPU iowait >60%, sort processes by I/O read and write
  • -
  • If CPU >70%, sort processes by CPU usage
  • -
  • If MEM >70%, sort processes by memory usage
  • -
-
-
b
-
Switch between bit/s or Byte/s for network I/O
-
c
-
Sort processes by CPU usage
-
d
-
Show/hide disk I/O stats
-
f
-
Show/hide file system stats
-
h
-
Show/hide the help screen
-
i
-
Sort processes by I/O rate (may need root privileges on some OSes)
-
l
-
Show/hide log messages
-
m
-
Sort processes by MEM usage
-
n
-
Show/hide network stats
-
p
-
Sort processes by name
-
q
-
Quit
-
s
-
Show/hide sensors stats (only available with -e flag)
-
t
-
View network I/O as combination
-
u
-
View cumulative network I/O
-
w
-
Delete finished warning log messages
-
x
-
Delete finished warning and critical log messages
-
y
-
Show/hide hddtemp stats (only available with -y flag)
-
1
-
Switch between global CPU and per-CPU stats
-
-
-
-
-

Configuration

-

No configuration file is mandatory to use Glances.

-

Furthermore a configuration file is needed for setup limits and/or monitored processes list.

-

By default, the configuration file is under:

- --- - - - - - - - -
Linux:/etc/glances/glances.conf
*BSD and OS X:/usr/local/etc/glances/glances.conf
Windows:%APPDATA%\glances\glances.conf
-

On Windows XP, the %APPDATA% path is:

-
C:\Documents and Settings\<User>\Application Data
-
-
-

Since Windows Vista and newer versions:

-
C:\Users\<User>\AppData\Roaming
-
-
-

You can override the default configuration, located in one of the above -directories on your system, except for Windows.

-

Just copy the glances.conf file to your $XDG_CONFIG_HOME directory, e.g. Linux:

-
mkdir -p $XDG_CONFIG_HOME/glances
-cp /etc/glances/glances.conf $XDG_CONFIG_HOME/glances/
-
-
-

On OS X, you should copy the configuration file to ~/Library/Application Support/glances/.

-
-
-

Anatomy of the application

-
-

Legend

-
-
GREEN stat counter is "OK"
-
BLUE stat counter is "CAREFUL"
-
MAGENTA stat counter is "WARNING"
-
RED stat counter is "CRITICAL"
-
-
- -
-

CPU

-

Short view:

-_images/cpu.png -

If enough horizontal space is available, extended CPU informations are displayed.

-

Extended view:

-_images/cpu-wide.png -

To switch to per-CPU stats, just hit the 1 key:

-_images/per-cpu.png -

The CPU stats are shown as a percentage and for the configured refresh time. -The total CPU usage is displayed on the first line.

-
-
If user|system|nice CPU is <50%, then status is set to "OK"
-
If user|system|nice CPU is >50%, then status is set to "CAREFUL"
-
If user|system|nice CPU is >70%, then status is set to "WARNING"
-
If user|system|nice CPU is >90%, then status is set to "CRITICAL"
-
-

Note: limit values can be overwritten in the configuration file under the [cpu] section.

-
-
-

Load

-_images/load.png -

On the No Sheep blog, Zachary Tirrell defines the average load [1]:

-
-
“In short it is the average sum of the number of processes -waiting in the run-queue plus the number currently executing -over 1, 5, and 15 minute time periods.”
-

Glances gets the number of CPU core to adapt the alerts. -Alerts on average load are only set on 5 and 15 min. -The first line also display the number of CPU core.

-
-
If average load is <0.7*core, then status is set to "OK"
-
If average load is >0.7*core, then status is set to "CAREFUL"
-
If average load is >1*core, then status is set to "WARNING"
-
If average load is >5*core, then status is set to "CRITICAL"
-
-

Note: limit values can be overwritten in the configuration file under the [load] section.

-
-
-

Memory

-

Glances uses two columns: one for the RAM and another one for the Swap.

-_images/mem.png -

If enough space is available, Glances displays extended informations:

-_images/mem-wide.png -

With Glances, alerts are only set for on used memory and used swap.

-
-
If memory is <50%, then status is set to "OK"
-
If memory is >50%, then status is set to "CAREFUL"
-
If memory is >70%, then status is set to "WARNING"
-
If memory is >90%, then status is set to "CRITICAL"
-
-

Note: limit values can be overwritten in the configuration file under the [memory] and [swap] sections.

-
-
-

Network

-_images/network.png -

Glances displays the network interface bit rate. The unit is adapted -dynamically (bits per second, kbits per second, Mbits per second, etc).

-

Alerts are only set if the network interface maximum speed is available.

-

For example, on a 100 Mbps ethernet interface, the warning status is set -if the bit rate is higher than 70 Mbps.

-
-
If bit rate is <50%, then status is set to "OK"
-
If bit rate is >50%, then status is set to "CAREFUL"
-
If bit rate is >70%, then status is set to "WARNING"
-
If bit rate is >90%, then status is set to "CRITICAL"
-
-
-
-

Sensors

-

Glances can displays the sensors informations trough lm-sensors (only available on Linux).

-

As of lm-sensors, a filter is processed in order to display temperature only:

-_images/sensors.png -

Glances can also grab hard disk temperature through the hddtemp daemon (see here [2] to install hddtemp on your system):

-_images/hddtemp.png -

To enable the lm-sensors module:

-
$ glances -e
-
-
-

To enable the hddtemp module:

-
$ glances -y
-
-
-

There is no alert on this information.

-

Note: limit values can be overwritten in the configuration file under the [temperature] and [hddtemperature] sections.

-
-
-

Disk I/O

-_images/diskio.png -

Glances displays the disk I/O throughput. The unit is adapted dynamically.

-

Note: There is no alert on this information.

-
-
-

File system

-_images/fs.png -

Glances displays the used and total file system disk space. The unit is -adapted dynamically.

-

Alerts are set for used disk space:

-
-
If disk used is <50%, then status is set to "OK"
-
If disk used is >50%, then status is set to "CAREFUL"
-
If disk used is >70%, then status is set to "WARNING"
-
If disk used is >90%, then status is set to "CRITICAL"
-
-

Note: limit values can be overwritten in the configuration file under [filesystem] section.

-
-
-

Processes list

-

Compact view:

-_images/processlist.png -

Full view:

-_images/processlist-wide.png -

Three views are available for processes:

-
    -
  • Processes summary
  • -
  • Optional monitored processes list (new in 1.7)
  • -
  • Processes list
  • -
-

By default, or if you hit the a key, the processes list is automatically -sorted by CPU of memory usage.

-

Note: limit values can be overwritten in the configuration file under the [process] section.

-

The number of processes in the list is adapted to the screen size.

-
-
VIRT
-
Total program size (VMS)
-
RES
-
Resident set size (RSS)
-
CPU%
-
% of CPU used by the process
-
MEM%
-
% of MEM used by the process
-
PID
-
Process ID
-
USER
-
User ID per process
-
NI
-
Nice level of the process
-
S
-
Process status
-
TIME+
-
Cumulative CPU time used
-
IOR/s
-
Per process IO read rate (in Byte/s)
-
IOW/s
-
Per process IO write rate (in Byte/s)
-
NAME
-
Process name or command line
-
-

Process status legend:

-
-
R
-
running
-
S
-
sleeping (may be interrupted)
-
D
-
disk sleep (may not be interrupted)
-
T
-
traced/stopped
-
Z
-
zombie
-
-
-
-

Monitored processes list

-

New in version 1.7. Optional.

-

The monitored processes list allows user, through the configuration file, -to group processes and quickly show if the number of running process is not good.

-_images/monitored.png -

Each item is defined by:

-
    -
  • description: description of the processes (max 16 chars).
  • -
  • regex: regular expression of the processes to monitor.
  • -
  • command (optional): full path to shell command/script for extended stat. Should return a single line string. Use with caution.
  • -
  • countmin (optional): minimal number of processes. A warning will be displayed if number of processes < count.
  • -
  • countmax (optional): maximum number of processes. A warning will be displayed if number of processes > count.
  • -
-

Up to 10 items can be defined.

-

For example, if you want to monitor the Nginx processes on a Web server, the following definition should do the job:

-
[monitor]
-list_1_description=Nginx server
-list_1_regex=.*nginx.*
-list_1_command=nginx -v
-list_1_countmin=1
-list_1_countmax=4
-
-
-

If you also want to monitor the PHP-FPM daemon processes, you should add another item:

-
[monitor]
-list_1_description=Nginx server
-list_1_regex=.*nginx.*
-list_1_command=nginx -v
-list_1_countmin=1
-list_1_countmax=4
-list_1_description=PHP-FPM
-list_1_regex=.*php-fpm.*
-list_1_countmin=1
-list_1_countmax=20
-
-
-

In client/server mode, the list is defined on the server side. -A new method, called getAllMonitored, is available in the APIs and get the JSON representation of the monitored processes list.

-

Alerts are set as following:

-
-
If number of processes is 0, then status is set to "CRITICAL"
-
If number of processes is min < current < max, then status is set to "OK"
-
Else status is set to "WARNING"
-
-
-
-

Logs

-_images/logs.png -

A log messages list is displayed in the bottom of the screen if (and only if):

-
    -
  • at least one WARNING or CRITICAL alert was occurred
  • -
  • space is available in the bottom of the console/terminal
  • -
-

Each alert message displays the following information:

-
    -
  1. start date
  2. -
  3. end date
  4. -
  5. alert name
  6. -
  7. {min/avg/max} values or number of running processes for monitored processes list alerts
  8. -
-
- -
-
-

API documentation

-

Glances uses a XML-RPC server and can be used by another client software.

-

API documentation is available at https://github.com/nicolargo/glances/wiki/The-Glances-API-How-To

-
- -
- - -
-
-
-
-
-

Table Of Contents

- - -

Previous topic

-

Welcome to Glances’s documentation!

-

This Page

- - - -
-
-
-
- - - - \ No newline at end of file diff --git a/docs/_build/html/index.html b/docs/_build/html/index.html deleted file mode 100644 index 3c01848d..00000000 --- a/docs/_build/html/index.html +++ /dev/null @@ -1,146 +0,0 @@ - - - - - - - - - - Welcome to Glances’s documentation! — Glances 1.7.3 documentation - - - - - - - - - - - - - - -
-
-
-
- -
-

Welcome to Glances’s documentation!

-

Glances is a cross-platform curses-based monitoring tool written in Python.

-

It uses the psutil library and some internal code to get information from your system.

-https://raw.github.com/nicolargo/glances/master/docs/images/screenshot-wide.png -
-

Get the code

-

The source is available on GitHub.

-
- -
-
-

Indices and tables

- -
- - -
-
-
-
-
-

Table Of Contents

- - -

Next topic

-

Glances

-

This Page

- - - -
-
-
-
- - - - \ No newline at end of file diff --git a/docs/_build/html/objects.inv b/docs/_build/html/objects.inv deleted file mode 100644 index a36a6df0..00000000 Binary files a/docs/_build/html/objects.inv and /dev/null differ diff --git a/docs/_build/html/search.html b/docs/_build/html/search.html deleted file mode 100644 index 4f2d7afb..00000000 --- a/docs/_build/html/search.html +++ /dev/null @@ -1,101 +0,0 @@ - - - - - - - - - - Search — Glances 1.7.3 documentation - - - - - - - - - - - - - - - - - - - -
-
-
-
- -

Search

-
- -

- Please activate JavaScript to enable the search - functionality. -

-
-

- From here you can search these documents. Enter your search - words into the box below and click "search". Note that the search - function will automatically search for all of the words. Pages - containing fewer words won't appear in the result list. -

-
- - - -
- -
- -
- -
-
-
-
-
-
-
-
-
- - - - \ No newline at end of file diff --git a/docs/_build/html/searchindex.js b/docs/_build/html/searchindex.js deleted file mode 100644 index 10a73d18..00000000 --- a/docs/_build/html/searchindex.js +++ /dev/null @@ -1 +0,0 @@ -Search.setIndex({objects:{},terms:{represent:0,all:0,code:1,appdata:0,global:0,sleep:0,follow:0,disk:0,compact:0,middl:0,depend:0,program:0,swap:0,under:0,list_1_command:0,sourc:1,string:0,iowait:0,trough:0,pocess:[],level:0,list:0,item:0,rate:0,port:0,compat:0,index:1,hide:0,sum:0,access:0,delet:0,version:0,"new":0,net:0,method:0,full:0,mem:0,batinfo:0,here:0,address:0,path:0,legend:0,valu:0,wait:0,search:1,queue:0,throughput:0,list_1_countmax:0,modul:[0,1],unix:0,api:[0,1],xdg_config_hom:0,instal:0,total:0,unit:0,regex:0,from:[0,1],describ:0,memori:0,two:0,call:0,usr:0,sort:0,warn:0,flag:0,setup:0,work:0,can:0,root:0,overrid:0,prompt:0,process:0,indic:1,critic:0,minimum:0,caution:0,want:0,magenta:0,occur:0,end:0,fpm:0,anoth:0,write:0,how:0,low:0,csv:0,max:0,mai:0,data:0,averag:0,"short":0,footer:0,bind:0,counter:0,issu:0,inform:[0,1],"switch":0,curent:[],combin:0,allow:0,ethernet:0,order:0,hennion:0,cyberc:0,help:0,over:0,privileg:0,dynam:0,group:0,monitor:[0,1],fit:0,platform:[0,1],window:0,good:0,"return":0,python:[0,1],interrupt:0,introduct:[0,1],name:0,refresh:0,psutil:[0,1],mode:0,each:0,found:0,side:0,hard:0,connect:0,tirrel:0,shown:0,network:0,space:0,content:[0,1],adapt:0,sensor:0,red:0,free:0,standalon:0,base:[0,1],zombi:0,releas:0,"byte":0,care:0,mbit:0,filter:0,view:0,first:0,softwar:0,feel:0,number:0,system:[0,1],date:0,messag:0,size:0,sheep:0,given:0,script:0,interact:0,mkdir:0,capac:0,least:0,stori:0,cumul:0,termin:0,listen:0,shell:0,consol:0,option:0,tool:[0,1],copi:0,github:[0,1],hddtemp:0,list_1_regex:0,than:0,rss:0,remot:0,second:0,horizont:0,were:0,consumpt:0,minut:0,zachari:0,countmin:0,ran:0,ram:0,have:0,tabl:[0,1],need:0,min:0,note:0,also:0,ideal:0,client:0,which:0,green:0,singl:0,anatomi:[0,1],blue:0,trace:0,track:0,regular:0,"80x24":0,bsd:0,request:0,drive:0,section:0,show:0,xml:0,current:0,onli:0,locat:0,execut:0,copyright:0,configur:[0,1],written:[0,1],should:0,folder:0,local:0,overwritten:0,hit:0,contribut:0,get:[0,1],express:0,stop:0,report:0,requir:0,enabl:0,through:0,grab:0,septemb:[],where:0,summari:0,wiki:0,kernel:0,set:0,maximum:0,see:0,sec:0,statu:0,kei:0,list_1_descript:0,enough:0,between:0,attribut:0,hddtemperatur:0,august:[],extend:0,screen:0,job:0,addit:0,etc:0,com:0,load:0,simpli:0,color:0,period:0,header:0,rpc:0,linux:0,batteri:0,nicola:0,quit:0,three:0,sinc:0,json:0,quickli:0,present:0,mount:0,aim:0,defin:0,"while":0,abov:0,mandatori:0,glanc:[0,1],list_1_countmin:0,virt:0,conf:0,nicolargo:0,avg:0,welcom:1,minim:0,cross:[0,1],html:0,nosheep:0,document:[0,1],higher:0,finish:0,http:0,hostnam:0,iow:0,ior:0,alert:0,user:0,php:0,exampl:0,command:[0,1],thi:0,filesystem:0,left:0,just:0,percent:0,tcp:0,speed:0,web:0,except:0,blog:0,add:0,els:0,applic:[0,1],read:0,howto:0,nginx:0,temperatur:0,biz:0,press:0,bit:0,password:0,daemon:0,resid:0,manual:0,server:0,kbit:0,output:0,nice:0,page:1,www:0,some:[0,1],percentag:0,intern:1,librari:[0,1],bottom:0,definit:0,per:0,pysensor:0,exit:0,refer:[0,1],machin:0,core:0,plu:0,run:0,bold:0,usag:[0,1],column:0,roam:0,disabl:0,countmax:0,automat:0,mbp:0,your:[0,1],log:0,support:[0,1],avail:[0,1],start:0,interfac:0,ipv4:0,ipv6:0,newer:0,line:0,bug:0,count:0,"default":0,displai:0,limit:0,embed:0,featur:0,curs:[0,1],classic:0,pid:0,"char":0,novemb:0,file:0,vista:0,tip:0,virtual:[],you:0,architectur:0,stat:0,easili:0,furthermor:0,directori:0,descript:0,getallmonitor:0,time:0,cpu:0},objtypes:{},titles:["Glances","Welcome to Glances’s documentation!"],objnames:{},filenames:["glances-doc","index"]}) \ No newline at end of file diff --git a/docs/conf.py b/docs/conf.py index 6ad61442..0c304658 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- # # Glances documentation build configuration file, created by -# sphinx-quickstart on Tue Aug 20 13:33:45 2013. +# sphinx-quickstart on Tue Mar 25 19:57:21 2014. # # This file is execfile()d with the current directory set to its containing dir. # @@ -41,16 +41,16 @@ master_doc = 'index' # General information about the project. project = u'Glances' -copyright = u'2013, Nicolas Hennion' +copyright = u'2014, Nicolas Hennion' # 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 = '1.7.3' +version = '1.7.5' # The full version, including alpha/beta/rc tags. -release = '1.7.3' +release = '1.7.5' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. diff --git a/docs/glances-doc.html b/docs/glances-doc.html index 9cfb514d..0f668877 100644 --- a/docs/glances-doc.html +++ b/docs/glances-doc.html @@ -70,12 +70,12 @@ p.topic-title { font-weight: bold; } -pre.code { +pre { margin-left: 2em; margin-right: 2em; } -.console { +.console, .literal-block { background-color: #eeeeee; border: 1px solid #cccccc; max-width: 60em; @@ -123,70 +123,78 @@ td.option-group {

Glances

-

This manual describes Glances version 1.7.3.

-

Copyright © 2012-2013 Nicolas Hennion <nicolas@nicolargo.com>

-

November 2013

+

This manual describes Glances version 2.0.

+

Copyright © 2012-2014 Nicolas Hennion <nicolas@nicolargo.com>

+

June 2014

-

Introduction

-

Glances is a cross-platform curses-based monitoring tool which aims to -present a maximum of information in a minimum of space, ideally to fit -in a classical 80x24 terminal or higher to have additional information.

-

Glances can adapt dynamically the displayed information depending on the -terminal size. It can also work in a client/server mode for remote monitoring.

-

Glances is written in Python and uses the psutil library to get information from your system.

+

Introduction

+

Glances is a cross-platform curses-based system monitoring tool which +aims to present a maximum of information in a minimum of space, ideally +to fit in a classical 80x24 terminal or higher to have additional +information. It can adapt dynamically the displayed information depending +on the terminal size.

+

Glances can also work in client/server mode. Remote monitoring could be +done via terminal or web interface.

+

Glances is written in Python and uses the psutil library to get +information from your system.

Console (80x24)

images/screenshot.png

Full view (>80x24)

images/screenshot-wide.png +

Web interface (Firefox)

+images/screenshot-web.png
-

Usage

+

Usage

-

Standalone mode

+

Standalone Mode

Simply run:

 $ glances
 
-

Client/Server mode

-

If you want to remotely monitor a machine, called server, from another one, called client, -just run on the server:

+

Client/Server Mode

+

If you want to remotely monitor a machine, called server, from +another one, called client, just run on the server:

 server$ glances -s
 
@@ -195,90 +203,146 @@ just run on the server:

client$ glances -c @server

where @server is the IP address or hostname of the server.

-

In server mode, you can set the bind address -B ADDRESS and listening TCP port -p PORT.

+

In server mode, you can set the bind address -B ADDRESS and listening +TCP port -p PORT.

In client mode, you can set the TCP port of the server -p PORT.

-

Default binding address is 0.0.0.0 (Glances will listen on all the network interfaces) and TCP port is 61209.

+

You can also set a password to access to the server --password.

+

Default binding address is 0.0.0.0 (Glances will listen on all the +network interfaces) and TCP port is 61209.

In client/server mode, limits are set by the server side.

-

You can also set a password to access to the server -P password.

-

Glances is IPv6 compatible. Just use the -B :: option to bind to all IPv6 addresses.

+

Glances is IPv6 compatible. Just use the -B :: option to bind to +all IPv6 addresses.

+

As an experimental feature, if Glances server is not detected by the +client, the latter will try to grab stats using the SNMP protocol:

+
+client$ glances -c @snmpserver
+
+

Known issues: grab using SNMP is only validated for GNU/Linux with SNMP +v2/2c server.

+
+
+

Web Server Mode

+

If you want to remotely monitor a machine, called server, from any +device with a web browser, called client, just run on the server:

+
+server$ glances -w
+
+

and on the client enter the following URL in your favorite web browser:

+
+http://@server:61208
+
+

where @server is the IP address or hostname of the server.

+

The Glances web interface follows responsive web design principles.

+

Screenshot from Chrome on Android

+images/screenshot-web2.png
-

Command reference

+

Command Reference

-

Command-line options

+

Command-Line Options

- +-h, --help + - +-V, --version + - +-b, --byte + + + + + + + + + + - +--disable-bold + + + + - +--disable-fs + + + + + + + + + + - - - - - - - - - - - - - - - +--disable-log + + + + + + + - + - +-s, --server + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - +-1, --percpu +
--bDisplay network rate in Byte per second (default: bit per second)
show this help message and exit
--B IPBind server to the given IPv4/IPv6 address or hostname
show program's version number and exit
--c IPConnect to a Glances server by IPv4/IPv6 address or hostname
display network rate in byte per second
+-B BIND_ADDRESS, --bind BIND_ADDRESS
 bind server to the given IPv4/IPv6 address or hostname
+-c CLIENT, --client CLIENT
 connect to a Glances server by IPv4/IPv6 address or +hostname
+-C CONF_FILE, --config CONF_FILE
 path to the configuration file
--C FILEPath to the configuration file
disable bold mode in the terminal
+--disable-diskio
 disable disk I/O module
--dDisable disk I/O module
disable file system module
+--disable-network
 disable network module
+--disable-sensors
 disable sensors module
+--disable-process
 disable process module
--eEnable sensors module (requires pysensors, Linux-only)
--f FILESet the HTML output folder or CSV file
--hDisplay the help and exit
--mDisable mount module
--nDisable network module
--o OUTPUTDefine additional output (available: HTML or CSV)
--p PORTDefine the client/server TCP port (default: 61209)
--P PASSWORDDefine a client/server password
disable log module
+--output-csv OUTPUT_CSV
 export stats to a CSV file
+-p PORT, --port PORT
 define the client/server TCP port [default: 61209]
--passwordDefine a client/server password from the prompt
define a client/server password from the prompt or +file
--rDisable process list (for low CPU consumption)
run Glances in server mode
+--snmp-community SNMP_COMMUNITY
 SNMP community
+--snmp-port SNMP_PORT
 SNMP port
+--snmp-version SNMP_VERSION
 SNMP version (1, 2c or 3)
+--snmp-user SNMP_USER
 SNMP username (only for SNMPv3)
+--snmp-auth SNMP_AUTH
 SNMP authentication key (only for SNMPv3)
+-t TIME, --time TIME
 set refresh time in seconds [default: 3 sec]
+-w, --webserver
 run Glances in Web server mode
--sRun Glances in server mode
--t SECONDSSet refresh time in seconds (default: 3 sec)
--vDisplay the version and exit
--yEnable hddtemp module (requires hddtemp)
--zDo not use the bold color attribute
--1Start Glances in per-CPU mode
start Glances in per CPU mode
-

Interactive commands

+

Interactive Commands

The following commands (key pressed) are supported while in Glances:

a
@@ -300,7 +364,7 @@ just run on the server:

h
Show/hide the help screen
i
-
Sort processes by I/O rate (may need root privileges on some OSes)
+
Sort processes by I/O rate
l
Show/hide log messages
m
@@ -312,7 +376,7 @@ just run on the server:

q
Quit
s
-
Show/hide sensors stats (only available with -e flag)
+
Show/hide sensors stats
t
View network I/O as combination
u
@@ -321,8 +385,8 @@ just run on the server:

Delete finished warning log messages
x
Delete finished warning and critical log messages
-
y
-
Show/hide hddtemp stats (only available with -y flag)
+
z
+
Show/hide processes stats
1
Switch between global CPU and per-CPU stats
@@ -330,8 +394,11 @@ just run on the server:

Configuration

+

Caution! Glances version 1.x configuration files are not compatible +with the version 2.x.

No configuration file is mandatory to use Glances.

-

Furthermore a configuration file is needed for setup limits and/or monitored processes list.

+

Furthermore a configuration file is needed to set up limits, disks or +network interfaces to hide and/or monitored processes list.

By default, the configuration file is under:

@@ -346,24 +413,26 @@ just run on the server:

On Windows XP, the %APPDATA% path is:

-
-C:\Documents and Settings\<User>\Application Data
+
+C:\Documents and Settings\<User>\Application Data
 

Since Windows Vista and newer versions:

-
-C:\Users\<User>\AppData\Roaming
+
+C:\Users\<User>\AppData\Roaming
 

You can override the default configuration, located in one of the above directories on your system, except for Windows.

-

Just copy the glances.conf file to your $XDG_CONFIG_HOME directory, e.g. Linux:

+

Just copy the glances.conf file to your $XDG_CONFIG_HOME directory, +e.g., on Linux:

 mkdir -p $XDG_CONFIG_HOME/glances
-cp /etc/glances/glances.conf $XDG_CONFIG_HOME/glances/
+cp /usr/share/doc/glances/glances.conf $XDG_CONFIG_HOME/glances/
 
-

On OS X, you should copy the configuration file to ~/Library/Application Support/glances/.

+

On OS X, you should copy the configuration file to +~/Library/Application Support/glances/.

-

Anatomy of the application

+

Anatomy Of The Application

Legend

@@ -372,121 +441,127 @@ cp /etc/glances/glances.conf $XDG_CONFIG_HOME/glances/
MAGENTA stat counter is "WARNING"
RED stat counter is "CRITICAL"
+

Note: only stats with colored background will be logged in the alert +view.

CPU

Short view:

images/cpu.png -

If enough horizontal space is available, extended CPU informations are displayed.

+

If enough horizontal space is available, extended CPU information are +displayed.

Extended view:

images/cpu-wide.png

To switch to per-CPU stats, just hit the 1 key:

images/per-cpu.png -

The CPU stats are shown as a percentage and for the configured refresh time. -The total CPU usage is displayed on the first line.

+

The CPU stats are shown as a percentage and for the configured refresh +time. The total CPU usage is displayed on the first line.

-
If user|system|nice CPU is <50%, then status is set to "OK"
-
If user|system|nice CPU is >50%, then status is set to "CAREFUL"
-
If user|system|nice CPU is >70%, then status is set to "WARNING"
-
If user|system|nice CPU is >90%, then status is set to "CRITICAL"
+
If user|system CPU is <50%, then status is set to "OK"
+
If user|system CPU is >50%, then status is set to "CAREFUL"
+
If user|system CPU is >70%, then status is set to "WARNING"
+
If user|system CPU is >90%, then status is set to "CRITICAL"
-

Note: limit values can be overwritten in the configuration file under the [cpu] section.

+

Note: limit values can be overwritten in the configuration file under +the [cpu] and/or [percpu] sections.

Load

images/load.png -

On the No Sheep blog, Zachary Tirrell defines the average load [1]:

+

On the No Sheep blog, Zachary Tirrell defines the load average [1]:

"In short it is the average sum of the number of processes waiting in the run-queue plus the number currently executing -over 1, 5, and 15 minute time periods."
+over 1, 5, and 15 minutes time periods."

Glances gets the number of CPU core to adapt the alerts. -Alerts on average load are only set on 5 and 15 min. -The first line also display the number of CPU core.

+Alerts on load average are only set on 15 minutes time period. +The first line also displays the number of CPU core.

-
If average load is <0.7*core, then status is set to "OK"
-
If average load is >0.7*core, then status is set to "CAREFUL"
-
If average load is >1*core, then status is set to "WARNING"
-
If average load is >5*core, then status is set to "CRITICAL"
+
If load average is <0.7*core, then status is set to "OK"
+
If load average is >0.7*core, then status is set to "CAREFUL"
+
If load average is >1*core, then status is set to "WARNING"
+
If load average is >5*core, then status is set to "CRITICAL"
-

Note: limit values can be overwritten in the configuration file under the [load] section.

+

Note: limit values can be overwritten in the configuration file under +the [load] section.

Memory

-

Glances uses two columns: one for the RAM and another one for the Swap.

+

Glances uses two columns: one for the RAM and one for the SWAP.

images/mem.png -

If enough space is available, Glances displays extended informations:

+

If enough space is available, Glances displays extended information for +the RAM:

images/mem-wide.png -

With Glances, alerts are only set for on used memory and used swap.

+

Alerts are only set for used memory and used swap.

-
If memory is <50%, then status is set to "OK"
-
If memory is >50%, then status is set to "CAREFUL"
-
If memory is >70%, then status is set to "WARNING"
-
If memory is >90%, then status is set to "CRITICAL"
+
If used memory|swap is <50%, then status is set to "OK"
+
If used memory|swap is >50%, then status is set to "CAREFUL"
+
If used memory|swap is >70%, then status is set to "WARNING"
+
If used memory|swap is >90%, then status is set to "CRITICAL"
-

Note: limit values can be overwritten in the configuration file under the [memory] and [swap] sections.

+

Note: limit values can be overwritten in the configuration file under +the [memory] and/or [memswap] sections.

Network

images/network.png

Glances displays the network interface bit rate. The unit is adapted dynamically (bits per second, kbits per second, Mbits per second, etc).

-

Alerts are only set if the network interface maximum speed is available.

-

For example, on a 100 Mbps ethernet interface, the warning status is set -if the bit rate is higher than 70 Mbps.

-
-
If bit rate is <50%, then status is set to "OK"
-
If bit rate is >50%, then status is set to "CAREFUL"
-
If bit rate is >70%, then status is set to "WARNING"
-
If bit rate is >90%, then status is set to "CRITICAL"
-
-
-
-

Sensors

-

Glances can displays the sensors informations trough lm-sensors (only available on Linux).

-

As of lm-sensors, a filter is processed in order to display temperature only:

-images/sensors.png -

Glances can also grab hard disk temperature through the hddtemp daemon (see here [2] to install hddtemp on your system):

-images/hddtemp.png -

To enable the lm-sensors module:

-
-$ glances -e
-
-

To enable the hddtemp module:

-
-$ glances -y
-
-

There is no alert on this information.

-

Note: limit values can be overwritten in the configuration file under the [temperature] and [hddtemperature] sections.

+

Alerts are only set if the maximum speed per network interface is available +(see sample in the configuration file).

+

Note: it is possibile to define a list of network interfaces to hide +and per-interface limit values in the [network] section of the +configuration file.

-

Disk I/O

+

Disk I/O

images/diskio.png

Glances displays the disk I/O throughput. The unit is adapted dynamically.

-

Note: There is no alert on this information.

+

There is no alert on this information.

+

Note: it is possible to define a list of disks to hide under the +[diskio] section in the configuration file.

-

File system

+

File System

images/fs.png

Glances displays the used and total file system disk space. The unit is adapted dynamically.

-

Alerts are set for used disk space:

+

Alerts are set for used disk space.

-
If disk used is <50%, then status is set to "OK"
-
If disk used is >50%, then status is set to "CAREFUL"
-
If disk used is >70%, then status is set to "WARNING"
-
If disk used is >90%, then status is set to "CRITICAL"
+
If used disk is <50%, then status is set to "OK"
+
If used disk is >50%, then status is set to "CAREFUL"
+
If used disk is >70%, then status is set to "WARNING"
+
If used disk is >90%, then status is set to "CRITICAL"
-

Note: limit values can be overwritten in the configuration file under [filesystem] section.

+

Note: limit values can be overwritten in the configuration file under +the [filesystem] section.

+
+
+

Sensors

+

Glances can displays the sensors information using lm-sensors, +hddtemp and batinfo [2].

+

All of the above libraries are available only on Linux.

+

As of lm-sensors, a filter is being applied in order to display +temperature only.

+images/sensors.png +

There is no alert on this information.

+

Note: limit values can be overwritten in the configuration file under +the [sensors] section.

-

Processes list

+

Processes List

Compact view:

images/processlist.png

Full view:

@@ -494,80 +569,101 @@ adapted dynamically.

Three views are available for processes:

  • Processes summary
  • -
  • Optional monitored processes list (new in 1.7)
  • +
  • Optional monitored processes list (see below)
  • Processes list
-

By default, or if you hit the a key, the processes list is automatically -sorted by CPU of memory usage.

-

Note: limit values can be overwritten in the configuration file under the [process] section.

+

The processes summary line display:

+
    +
  • Tasks number (total number of processes)
  • +
  • Threads number
  • +
  • Running tasks number
  • +
  • Sleeping tasks number
  • +
  • Other tasks number (not running or sleeping)
  • +
  • Sort key
  • +
+

By default, or if you hit the a key, the processes list is +automatically sorted by:

+
    +
  • CPU if there is no alert (default behavior)
  • +
  • CPU if a CPU or LOAD alert is detected
  • +
  • MEM if a memory alert is detected
  • +
  • Disk I/O if a CPU iowait alert is detected
  • +

The number of processes in the list is adapted to the screen size.

-
VIRT
-
Total program size (VMS)
-
RES
-
Resident set size (RSS)
CPU%
% of CPU used by the process
MEM%
% of MEM used by the process
+
VIRT
+
Total program size aka Virtual Memory Size (VMS)
+
RES
+
Resident Set Size (RSS)
PID
Process ID
USER
-
User ID per process
+
User ID
NI
-
Nice level of the process
+
Nice level of the process (niceness other than 0 is highlighted)
S
-
Process status
+
Process status (running process is highlighted)
TIME+
Cumulative CPU time used
IOR/s
-
Per process IO read rate (in Byte/s)
+
Per process I/O read rate (in Byte/s)
IOW/s
-
Per process IO write rate (in Byte/s)
-
NAME
-
Process name or command line
+
Per process I/O write rate (in Byte/s)
+
COMMAND
+
Process command line (process name is highlighted)

Process status legend:

R
-
running
+
Running
S
-
sleeping (may be interrupted)
+
Sleeping (may be interrupted)
D
-
disk sleep (may not be interrupted)
+
Disk sleep (may not be interrupted)
T
-
traced/stopped
+
Traced / Stopped
Z
-
zombie
+
Zombie
+

Note: limits values can be overwritten in the configuration file under +the [process] section.

-

Monitored processes list

-

New in version 1.7. Optional.

+

Monitored Processes List

The monitored processes list allows user, through the configuration file, -to group processes and quickly show if the number of running process is not good.

+to group processes and quickly show if the number of running processes is +not good.

images/monitored.png

Each item is defined by:

  • description: description of the processes (max 16 chars).
  • regex: regular expression of the processes to monitor.
  • -
  • command (optional): full path to shell command/script for extended stat. Should return a single line string. Use with caution.
  • -
  • countmin (optional): minimal number of processes. A warning will be displayed if number of processes < count.
  • -
  • countmax (optional): maximum number of processes. A warning will be displayed if number of processes > count.
  • +
  • command (optional): full path to shell command/script for extended +stat. Should return a single line string. Use with caution.
  • +
  • countmin (optional): minimal number of processes. A warning will +be displayed if number of processes < count.
  • +
  • countmax (optional): maximum number of processes. A warning will +be displayed if number of processes > count.

Up to 10 items can be defined.

-

For example, if you want to monitor the Nginx processes on a Web server, the following definition should do the job:

-
-[monitor]
+

For example, if you want to monitor the Nginx processes on a Web server, +the following definition should do the job:

+
+[monitor]
 list_1_description=Nginx server
 list_1_regex=.*nginx.*
 list_1_command=nginx -v
 list_1_countmin=1
-list_1_countmax=4
+list_1_countmax=4
 
-

If you also want to monitor the PHP-FPM daemon processes, you should add another item:

-
-[monitor]
+

If you also want to monitor the PHP-FPM daemon processes, you should add +another item:

+
+[monitor]
 list_1_description=Nginx server
 list_1_regex=.*nginx.*
 list_1_command=nginx -v
@@ -576,10 +672,11 @@ list_1_countmax=4
 list_1_description=PHP-FPM
 list_1_regex=.*php-fpm.*
 list_1_countmin=1
-list_1_countmax=20
+list_1_countmax=20
 

In client/server mode, the list is defined on the server side. -A new method, called getAllMonitored, is available in the APIs and get the JSON representation of the monitored processes list.

+A new method, called getAllMonitored, is available in the APIs and +get the JSON representation of the monitored processes list.

Alerts are set as following:

If number of processes is 0, then status is set to "CRITICAL"
@@ -590,42 +687,78 @@ A new method, called getAllMonitored, is available in the APIs and get the JSON

Logs

images/logs.png -

A log messages list is displayed in the bottom of the screen if (and only if):

+

A log messages list is displayed in the bottom of the screen if (and +only if):

  • at least one WARNING or CRITICAL alert was occurred
  • space is available in the bottom of the console/terminal

Each alert message displays the following information:

    -
  1. start date
  2. -
  3. end date
  4. +
  5. start datetime
  6. +
  7. duration if alert is terminated or ongoing if the alert is still in +progress
  8. alert name
  9. -
  10. {min/avg/max} values or number of running processes for monitored processes list alerts
  11. +
  12. {min,avg,max} values or number of running processes for monitored +processes list alerts
- +
+

Other Outputs

+

It is possible to export statistics to CSV file.

+
+$ glances --output-csv /tmp/glances.csv
+
+

CSV files have two lines per stats:

+
    +
  • Stats description
  • +
  • Stats (comma separated)
  • +
-

API documentation

+

API Documentation

Glances uses a XML-RPC server and can be used by another client software.

-

API documentation is available at https://github.com/nicolargo/glances/wiki/The-Glances-API-How-To

+

<<<<<<< HEAD +API documentation is available at https://github.com/nicolargo/glances/wiki/The-Glances-API-How-To

+
+
+

Other outputs

+

Thanks to the -o (output) option, it is possible to export statistics to CSV or HTML files.

+
+$ glances -o CSV -f /tmp
+
+

The CSV output file is named glances.csv.

+

CSV files have on line per stats:

+
    +
  • load,load1,load5,load15
  • +
  • mem,total,used,free
  • +
  • swap,total,used,free
  • +
  • cpu,user,system,nice,idle,iowait,irq
  • +
+
+$ glances -o HTML -f /tmp
+
+

The HTML output file is named glances.html.

+
+
+

Note: The css and img folders (glances/data) should be in the /tmp folder.

+
+

System Message: WARNING/2 (./docs/glances-doc.rst, line 628)

+

Title underline too short.

+
+*Note*: The css and img folders (glances/data) should be in the /tmp folder.
+=======
+
+
+

API documentation is available at +https://github.com/nicolargo/glances/wiki/The-Glances-2.x-API-How-to. +>>>>>>> release/v2.0

-

Support

-

To report a bug or a feature request use the bug tracking system at https://github.com/nicolargo/glances/issues

+

Support

+

To report a bug or a feature request use the bug tracking system at +https://github.com/nicolargo/glances/issues.

Feel free to contribute!

@@ -636,13 +769,7 @@ is installed on your system then Glances displays the available percent capacity
- - -
[2]http://www.cyberciti.biz/tips/howto-monitor-hard-drive-temperature.html
- - - - +
[3]https://github.com/nicolargo/batinfo
[2]https://github.com/nicolargo/batinfo
diff --git a/docs/glances-doc.rst b/docs/glances-doc.rst index 7181b174..cea11d38 100644 --- a/docs/glances-doc.rst +++ b/docs/glances-doc.rst @@ -6,23 +6,24 @@ This manual describes *Glances* version 2.0. Copyright © 2012-2014 Nicolas Hennion -May 2014 +June 2014 .. contents:: Table of Contents Introduction ============ -Glances is a cross-platform curses-based monitoring tool which aims to -present a maximum of information in a minimum of space, ideally to fit -in a classical 80x24 terminal or higher to have additional information. -Glances can adapt dynamically the displayed information depending on the -terminal size. +Glances is a cross-platform curses-based system monitoring tool which +aims to present a maximum of information in a minimum of space, ideally +to fit in a classical 80x24 terminal or higher to have additional +information. It can adapt dynamically the displayed information depending +on the terminal size. -Glances can also work in a client/server mode. Remote monitoring could be -done via terminal or Web interface. +Glances can also work in client/server mode. Remote monitoring could be +done via terminal or web interface. -Glances is written in Python and uses the `psutil`_ library to get information from your system. +Glances is written in Python and uses the `psutil`_ library to get +information from your system. Console (80x24) @@ -39,7 +40,7 @@ Web interface (Firefox) Usage ===== -Standalone mode +Standalone Mode --------------- Simply run: @@ -48,10 +49,11 @@ Simply run: $ glances -Client/Server mode +Client/Server Mode ------------------ -If you want to remotely monitor a machine, called ``server``, from another one, called ``client``, just run on the server: +If you want to remotely monitor a machine, called ``server``, from +another one, called ``client``, just run on the server: .. code-block:: console @@ -65,89 +67,100 @@ and on the client: where ``@server`` is the IP address or hostname of the server. -In server mode, you can set the bind address ``-B ADDRESS`` and listening TCP port ``-p PORT``. +In server mode, you can set the bind address ``-B ADDRESS`` and listening +TCP port ``-p PORT``. In client mode, you can set the TCP port of the server ``-p PORT``. You can also set a password to access to the server ``--password``. -Default binding address is ``0.0.0.0`` (Glances will listen on all the network interfaces) and TCP port is ``61209``. +Default binding address is ``0.0.0.0`` (Glances will listen on all the +network interfaces) and TCP port is ``61209``. In client/server mode, limits are set by the server side. -Glances is ``IPv6`` compatible. Just use the ``-B ::`` option to bind to all IPv6 addresses. +Glances is ``IPv6`` compatible. Just use the ``-B ::`` option to bind to +all IPv6 addresses. -As an experimental feature, if Glances server is not detected by the client, this last one try to grab stats using the SNMP protocol: +As an experimental feature, if Glances server is not detected by the +client, the latter will try to grab stats using the ``SNMP`` protocol: .. code-block:: console - client$ glances -c @snmpserver + client$ glances -c @snmpserver -Known limitation: Grab using SNMP is only validated for GNU/Linux operating system with SNMP v2/2c server. +Known issues: grab using SNMP is only validated for GNU/Linux with SNMP +v2/2c server. -Web Server mode ----------------- +Web Server Mode +--------------- -If you want to remotely monitor a machine, called ``server``, from any device with a Web Browser (called ``client``), just run on the server: +If you want to remotely monitor a machine, called ``server``, from any +device with a web browser, called ``client``, just run on the server: .. code-block:: console server$ glances -w -and on the client, enter the following URL in your favorite Web Browser: +and on the client enter the following URL in your favorite web browser: - http:\\@server:61208\ +:: + + http://@server:61208 where ``@server`` is the IP address or hostname of the server. -The Glances Web interface is responsive web designed (Android device screenshot): +The Glances web interface follows responsive web design principles. + +Screenshot from Chrome on Android .. image:: images/screenshot-web2.png -Command reference +Command Reference ================= -Command-line options +Command-Line Options -------------------- -h, --help show this help message and exit --V, --version show program's version number and exit +-V, --version show program's version number and exit -b, --byte display network rate in byte per second -B BIND_ADDRESS, --bind BIND_ADDRESS - bind server to the given IPv4/IPv6 address or hostname + bind server to the given IPv4/IPv6 address or hostname -c CLIENT, --client CLIENT - connect to a Glances server by IPv4/IPv6 address or - hostname + connect to a Glances server by IPv4/IPv6 address or + hostname -C CONF_FILE, --config CONF_FILE - path to the configuration file + path to the configuration file --disable-bold disable bold mode in the terminal --disable-diskio disable disk I/O module ---disable-fs disable filesystem module +--disable-fs disable file system module --disable-network disable network module --disable-sensors disable sensors module --disable-process disable process module --disable-log disable log module --output-csv OUTPUT_CSV - export stats to a csv file + export stats to a CSV file -p PORT, --port PORT define the client/server TCP port [default: 61209] ---password define a client/server password from the prompt/file +--password define a client/server password from the prompt or + file -s, --server run Glances in server mode --snmp-community SNMP_COMMUNITY - SNMP community + SNMP community --snmp-port SNMP_PORT - SNMP port + SNMP port --snmp-version SNMP_VERSION - SNMP version (1, 2c or 3) + SNMP version (1, 2c or 3) --snmp-user SNMP_USER - SNMP username (only for SNMPv3) + SNMP username (only for SNMPv3) --snmp-auth SNMP_AUTH - SNMP authentication key (only for SNMPv3) + SNMP authentication key (only for SNMPv3) -t TIME, --time TIME set refresh time in seconds [default: 3 sec] --w, --webserver run Glances in web server mode +-w, --webserver run Glances in Web server mode -1, --percpu start Glances in per CPU mode -Interactive commands +Interactive Commands -------------------- The following commands (key pressed) are supported while in Glances: @@ -169,7 +182,7 @@ The following commands (key pressed) are supported while in Glances: ``h`` Show/hide the help screen ``i`` - Sort processes by I/O rate (may need root privileges on some OSes) + Sort processes by I/O rate ``l`` Show/hide log messages ``m`` @@ -190,19 +203,21 @@ The following commands (key pressed) are supported while in Glances: Delete finished warning log messages ``x`` Delete finished warning and critical log messages -``y`` - Show/hide hddtemp stats +``z`` + Show/hide processes stats ``1`` Switch between global CPU and per-CPU stats Configuration ============= -**Caution: be aware that the Glances version 1.x configurations files are not comaptible with the version 2.x.** +**Caution! Glances version 1.x configuration files are not compatible +with the version 2.x.** No configuration file is mandatory to use Glances. -Furthermore a configuration file is needed for setup limits, disks or network interfaces to hide and/or monitored processes list. +Furthermore a configuration file is needed to set up limits, disks or +network interfaces to hide and/or monitored processes list. By default, the configuration file is under: @@ -212,29 +227,31 @@ By default, the configuration file is under: On Windows XP, the ``%APPDATA%`` path is: -.. code-block:: console +:: C:\Documents and Settings\\Application Data Since Windows Vista and newer versions: -.. code-block:: console +:: C:\Users\\AppData\Roaming You can override the default configuration, located in one of the above directories on your system, except for Windows. -Just copy the ``glances.conf`` file to your ``$XDG_CONFIG_HOME`` directory, e.g. Linux: +Just copy the ``glances.conf`` file to your ``$XDG_CONFIG_HOME`` directory, +e.g., on Linux: .. code-block:: console mkdir -p $XDG_CONFIG_HOME/glances - cp /etc/glances/glances.conf $XDG_CONFIG_HOME/glances/ + cp /usr/share/doc/glances/glances.conf $XDG_CONFIG_HOME/glances/ -On OS X, you should copy the configuration file to ``~/Library/Application Support/glances/``. +On OS X, you should copy the configuration file to +``~/Library/Application Support/glances/``. -Anatomy of the application +Anatomy Of The Application ========================== Legend @@ -245,17 +262,19 @@ Legend | ``MAGENTA`` stat counter is ``"WARNING"`` | ``RED`` stat counter is ``"CRITICAL"`` -Note: Only stats with colored background will be logged in the alert view. +*Note*: only stats with colored background will be logged in the alert +view. Header ------ .. image:: images/header.png -The header shows the hostname, OS name, release version, platform architecture and system uptime (on the upper right). -Additionnaly, on GNU/Linux operating system, it shows also the kernel version. +The header shows the hostname, OS name, release version, platform +architecture and system uptime (on the upper right corner). +Additionally, on GNU/Linux, it also shows the kernel version. -In client mode, the server connection status is displayed: +In client mode, the server connection status is displayed. Connected: @@ -272,7 +291,8 @@ Short view: .. image:: images/cpu.png -If enough horizontal space is available, extended CPU informations are displayed. +If enough horizontal space is available, extended CPU information are +displayed. Extended view: @@ -282,57 +302,61 @@ To switch to per-CPU stats, just hit the ``1`` key: .. image:: images/per-cpu.png -The CPU stats are shown as a percentage and for the configured refresh time. -The total CPU usage is displayed on the first line. +The CPU stats are shown as a percentage and for the configured refresh +time. The total CPU usage is displayed on the first line. -| If user|system|iowait CPU is ``<50%``, then status is set to ``"OK"`` -| If user|system|iowait CPU is ``>50%``, then status is set to ``"CAREFUL"`` -| If user|system|iowait CPU is ``>70%``, then status is set to ``"WARNING"`` -| If user|system|iowait CPU is ``>90%``, then status is set to ``"CRITICAL"`` +| If user|system CPU is ``<50%``, then status is set to ``"OK"`` +| If user|system CPU is ``>50%``, then status is set to ``"CAREFUL"`` +| If user|system CPU is ``>70%``, then status is set to ``"WARNING"`` +| If user|system CPU is ``>90%``, then status is set to ``"CRITICAL"`` -*Note*: limit values can be overwritten in the configuration file under the ``[cpu]`` or/and ``[percpu]`` sections. +*Note*: limit values can be overwritten in the configuration file under +the ``[cpu]`` and/or ``[percpu]`` sections. Load ---- .. image:: images/load.png -On the *No Sheep* blog, *Zachary Tirrell* defines the average load [1]_: +On the *No Sheep* blog, *Zachary Tirrell* defines the load average [1]_: "In short it is the average sum of the number of processes waiting in the run-queue plus the number currently executing over 1, 5, and 15 minutes time periods." Glances gets the number of CPU core to adapt the alerts. -Alerts on average load are only set on 15 minutes time period. -The first line also display the number of CPU core. +Alerts on load average are only set on 15 minutes time period. +The first line also displays the number of CPU core. -| If average load is ``<0.7*core``, then status is set to ``"OK"`` -| If average load is ``>0.7*core``, then status is set to ``"CAREFUL"`` -| If average load is ``>1*core``, then status is set to ``"WARNING"`` -| If average load is ``>5*core``, then status is set to ``"CRITICAL"`` +| If load average is ``<0.7*core``, then status is set to ``"OK"`` +| If load average is ``>0.7*core``, then status is set to ``"CAREFUL"`` +| If load average is ``>1*core``, then status is set to ``"WARNING"`` +| If load average is ``>5*core``, then status is set to ``"CRITICAL"`` -*Note*: limit values can be overwritten in the configuration file under the ``[load]`` section. +*Note*: limit values can be overwritten in the configuration file under +the ``[load]`` section. Memory ------ -Glances uses two columns: one for the ``RAM`` and another one for the ``SWAP``. +Glances uses two columns: one for the ``RAM`` and one for the ``SWAP``. .. image:: images/mem.png -If enough space is available, Glances displays extended informations for the ``RAM``: +If enough space is available, Glances displays extended information for +the ``RAM``: .. image:: images/mem-wide.png -With Glances, alerts are only set for used memory and swap. +Alerts are only set for used memory and used swap. -| If memory is ``<50%``, then status is set to ``"OK"`` -| If memory is ``>50%``, then status is set to ``"CAREFUL"`` -| If memory is ``>70%``, then status is set to ``"WARNING"`` -| If memory is ``>90%``, then status is set to ``"CRITICAL"`` +| If used memory|swap is ``<50%``, then status is set to ``"OK"`` +| If used memory|swap is ``>50%``, then status is set to ``"CAREFUL"`` +| If used memory|swap is ``>70%``, then status is set to ``"WARNING"`` +| If used memory|swap is ``>90%``, then status is set to ``"CRITICAL"`` -*Note*: limit values can be overwritten in the configuration file under the ``[memory]`` and ``[memswap]`` sections. +*Note*: limit values can be overwritten in the configuration file under +the ``[memory]`` and/or ``[memswap]`` sections. Network ------- @@ -342,9 +366,12 @@ Network Glances displays the network interface bit rate. The unit is adapted dynamically (bits per second, kbits per second, Mbits per second, etc). -Alerts are only set if the network interface maximum speed is available (see sample in the configuration file). +Alerts are only set if the maximum speed per network interface is available +(see sample in the configuration file). -*Note*: In the `[network]`` section of the configuration file, you can define a list of network interfaces to hide and per interface limits value. +*Note*: it is possibile to define a list of network interfaces to hide +and per-interface limit values in the ``[network]`` section of the +configuration file. Disk I/O -------- @@ -353,11 +380,12 @@ Disk I/O Glances displays the disk I/O throughput. The unit is adapted dynamically. -*Note*: There is no alert on this information. +There is no alert on this information. -*Note*: In the configuration file, you can define a list of disk to hide. +*Note*: it is possible to define a list of disks to hide under the +``[diskio]`` section in the configuration file. -File system +File System ----------- .. image:: images/fs.png @@ -365,33 +393,35 @@ File system Glances displays the used and total file system disk space. The unit is adapted dynamically. -Alerts are set for used disk space: +Alerts are set for used disk space. -| If disk used is ``<50%``, then status is set to ``"OK"`` -| If disk used is ``>50%``, then status is set to ``"CAREFUL"`` -| If disk used is ``>70%``, then status is set to ``"WARNING"`` -| If disk used is ``>90%``, then status is set to ``"CRITICAL"`` +| If used disk is ``<50%``, then status is set to ``"OK"`` +| If used disk is ``>50%``, then status is set to ``"CAREFUL"`` +| If used disk is ``>70%``, then status is set to ``"WARNING"`` +| If used disk is ``>90%``, then status is set to ``"CRITICAL"`` -*Note*: limit values can be overwritten in the configuration file under ``[filesystem]`` section. +*Note*: limit values can be overwritten in the configuration file under +the ``[filesystem]`` section. Sensors ------- -Glances can displays the sensors information trough `lm-sensors` (only available on GNU/Linux), HDDTemp and BatInfo. +Glances can displays the sensors information using `lm-sensors`, +`hddtemp` and `batinfo` [2]_. -As of lm-sensors, a filter is processed in order to display temperature only: +All of the above libraries are available only on Linux. + +As of lm-sensors, a filter is being applied in order to display +temperature only. .. image:: images/sensors.png -Glances can also grab hard disk temperature through the `hddtemp` daemon (see here [2]_ to install hddtemp on your system): - -.. image:: images/hddtemp.png - There is no alert on this information. -*Note*: limit values can be overwritten in the configuration file under the ``[sensors]`` section. +*Note*: limit values can be overwritten in the configuration file under +the ``[sensors]`` section. -Processes list +Processes List -------------- Compact view: @@ -405,25 +435,25 @@ Full view: Three views are available for processes: * Processes summary -* Optional monitored processes list (see bellow) +* Optional monitored processes list (see below) * Processes list The processes summary line display: * Tasks number (total number of processes) -* Threads number +* Threads number * Running tasks number * Sleeping tasks number * Other tasks number (not running or sleeping) * Sort key -By default, or if you hit the ``a`` key, the processes list is automatically -sorted by: +By default, or if you hit the ``a`` key, the processes list is +automatically sorted by: -* CPU if there is no alert (default behavor) -* CPU if a CPU or LOAD alert is detected -* MEM if a memory alert is detected -* DiskIO if a CPU IOWait alert is detected +* ``CPU`` if there is no alert (default behavior) +* ``CPU`` if a CPU or LOAD alert is detected +* ``MEM`` if a memory alert is detected +* ``Disk I/O`` if a CPU iowait alert is detected The number of processes in the list is adapted to the screen size. @@ -432,27 +462,27 @@ The number of processes in the list is adapted to the screen size. ``MEM%`` % of MEM used by the process ``VIRT`` - Total program size (VMS) + Total program size aka Virtual Memory Size (VMS) ``RES`` - Resident set size (RSS) + Resident Set Size (RSS) ``PID`` Process ID ``USER`` User ID ``NI`` - Nice level of the process + Nice level of the process (niceness other than 0 is highlighted) ``S`` - Process status (see details bellow) (running process is highlighted) + Process status (running process is highlighted) ``TIME+`` Cumulative CPU time used ``IOR/s`` - Per process IO read rate (in Byte/s) + Per process I/O read rate (in Byte/s) ``IOW/s`` - Per process IO write rate (in Byte/s) + Per process I/O write rate (in Byte/s) ``COMMAND`` Process command line (process name is highlighted) -Process Status legend: +Process status legend: ``R`` Running @@ -465,13 +495,15 @@ Process Status legend: ``Z`` Zombie -*Note*: limits values can be overwritten in the configuration file under the ``[process]`` section. +*Note*: limits values can be overwritten in the configuration file under +the ``[process]`` section. -Monitored processes list +Monitored Processes List ------------------------ The monitored processes list allows user, through the configuration file, -to group processes and quickly show if the number of running process is not good. +to group processes and quickly show if the number of running processes is +not good. .. image:: images/monitored.png @@ -479,15 +511,19 @@ Each item is defined by: * ``description``: description of the processes (max 16 chars). * ``regex``: regular expression of the processes to monitor. -* ``command`` (optional): full path to shell command/script for extended stat. Should return a single line string. Use with caution. -* ``countmin`` (optional): minimal number of processes. A warning will be displayed if number of processes < count. -* ``countmax`` (optional): maximum number of processes. A warning will be displayed if number of processes > count. +* ``command`` (optional): full path to shell command/script for extended + stat. Should return a single line string. Use with caution. +* ``countmin`` (optional): minimal number of processes. A warning will + be displayed if number of processes < count. +* ``countmax`` (optional): maximum number of processes. A warning will + be displayed if number of processes > count. Up to 10 items can be defined. -For example, if you want to monitor the Nginx processes on a Web server, the following definition should do the job: +For example, if you want to monitor the Nginx processes on a Web server, +the following definition should do the job: -.. code-block:: console +:: [monitor] list_1_description=Nginx server @@ -496,9 +532,10 @@ For example, if you want to monitor the Nginx processes on a Web server, the fol list_1_countmin=1 list_1_countmax=4 -If you also want to monitor the PHP-FPM daemon processes, you should add another item: +If you also want to monitor the PHP-FPM daemon processes, you should add +another item: -.. code-block:: console +:: [monitor] list_1_description=Nginx server @@ -512,7 +549,8 @@ If you also want to monitor the PHP-FPM daemon processes, you should add another list_1_countmax=20 In client/server mode, the list is defined on the server side. -A new method, called getAllMonitored, is available in the APIs and get the JSON representation of the monitored processes list. +A new method, called `getAllMonitored`, is available in the APIs and +get the JSON representation of the monitored processes list. Alerts are set as following: @@ -525,27 +563,23 @@ Logs .. image:: images/logs.png -A log messages list is displayed in the bottom of the screen if (and only if): +A log messages list is displayed in the bottom of the screen if (and +only if): - at least one ``WARNING`` or ``CRITICAL`` alert was occurred - space is available in the bottom of the console/terminal Each alert message displays the following information: -1. start date -2. duration if alert is terminated or ongoing if the alert is on going +1. start datetime +2. duration if alert is terminated or `ongoing` if the alert is still in + progress 3. alert name -4. {min/avg/max} values or number of running processes for monitored processes list alerts +4. {min,avg,max} values or number of running processes for monitored + processes list alerts -API documentation -================= - -Glances uses a `XML-RPC server`_ and can be used by another client software. - -API documentation is available at https://github.com/nicolargo/glances/wiki/The-Glances-2.x-API-How-to - -Others outputs -============== +Other Outputs +============= It is possible to export statistics to CSV file. @@ -558,17 +592,55 @@ CSV files have two lines per stats: - Stats description - Stats (comma separated) +API Documentation +================= + +Glances uses a `XML-RPC server`_ and can be used by another client software. + +<<<<<<< HEAD +API documentation is available at https://github.com/nicolargo/glances/wiki/The-Glances-API-How-To + +Other outputs +============= + +Thanks to the -o (output) option, it is possible to export statistics to `CSV` or `HTML` files. + +.. code-block:: console + + $ glances -o CSV -f /tmp + +The CSV output file is named ``glances.csv``. + +CSV files have on line per stats: + +- load,load1,load5,load15 +- mem,total,used,free +- swap,total,used,free +- cpu,user,system,nice,idle,iowait,irq + +.. code-block:: console + + $ glances -o HTML -f /tmp + +The HTML output file is named ``glances.html``. + +*Note*: The css and img folders (glances/data) should be in the /tmp folder. +======= +API documentation is available at +https://github.com/nicolargo/glances/wiki/The-Glances-2.x-API-How-to. +>>>>>>> release/v2.0 + Support ======= -To report a bug or a feature request use the bug tracking system at https://github.com/nicolargo/glances/issues +To report a bug or a feature request use the bug tracking system at +https://github.com/nicolargo/glances/issues. Feel free to contribute! .. [1] http://nosheep.net/story/defining-unix-load-average/ -.. [2] http://www.cyberciti.biz/tips/howto-monitor-hard-drive-temperature.html -.. [3] https://github.com/nicolargo/batinfo +.. [2] https://github.com/nicolargo/batinfo .. _psutil: https://code.google.com/p/psutil/ .. _XML-RPC server: http://docs.python.org/2/library/simplexmlrpcserver.html diff --git a/docs/images/footer.png b/docs/images/footer.png deleted file mode 100644 index 1145927d..00000000 Binary files a/docs/images/footer.png and /dev/null differ diff --git a/docs/images/network-sum.png b/docs/images/network-sum.png deleted file mode 100644 index c253462c..00000000 Binary files a/docs/images/network-sum.png and /dev/null differ diff --git a/docs/images/per-cpu.png b/docs/images/per-cpu.png index 004ff51c..dfd0be66 100644 Binary files a/docs/images/per-cpu.png and b/docs/images/per-cpu.png differ diff --git a/docs/images/screenshot-web2.png b/docs/images/screenshot-web2.png index 7a249b78..30b3c997 100644 Binary files a/docs/images/screenshot-web2.png and b/docs/images/screenshot-web2.png differ diff --git a/docs/index.rst b/docs/index.rst index b03349f3..81d714ee 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -25,4 +25,4 @@ Indices and tables * :ref:`genindex` * :ref:`modindex` -* :ref:`search` +* :ref:`search` \ No newline at end of file diff --git a/docs/style.css b/docs/style.css index 7dd4b97a..a6e38434 100644 --- a/docs/style.css +++ b/docs/style.css @@ -61,12 +61,12 @@ p.topic-title { font-weight: bold; } -pre.code { +pre { margin-left: 2em; margin-right: 2em; } -.console { +.console, .literal-block { background-color: #eeeeee; border: 1px solid #cccccc; max-width: 60em; diff --git a/glances/__init__.py b/glances/__init__.py index 618f227e..da204a35 100644 --- a/glances/__init__.py +++ b/glances/__init__.py @@ -16,9 +16,13 @@ # # You should have received a copy of the GNU Lesser General Public License # along with this program. If not, see . -""" -Init the Glances software -""" + +"""Init the Glances software.""" + +__appname__ = 'glances' +__version__ = '2.0' +__author__ = 'Nicolas Hennion ' +__license__ = 'LGPL' # Import system lib import gettext @@ -26,6 +30,21 @@ import locale import signal import sys +# Import psutil +try: + from psutil import __version__ as __psutil_version +except ImportError: + print('psutil library not found. Glances cannot start.') + sys.exit(1) + +# Check psutil version +psutil_min_version = (2, 0, 0) +psutil_version = tuple([int(num) for num in __psutil_version.split('.')]) +if psutil_version < psutil_min_version: + print('psutil version {0} detected.').format(__psutil_version) + print('psutil 2.0 or higher is needed. Glances cannot start.') + sys.exit(1) + # Import Glances libs # Note: others Glances libs will be imported optionally from glances.core.glances_globals import gettext_domain, locale_dir @@ -33,17 +52,12 @@ from glances.core.glances_main import GlancesMain def __signal_handler(signal, frame): - """ - Call back for CTRL-C - """ + """Callback for CTRL-C.""" end() def end(): - """ - Stop Glances - """ - + """Stop Glances.""" if core.is_standalone(): # Stop the standalone (CLI) standalone.end() @@ -59,8 +73,7 @@ def end(): def main(): - """ - Main entry point for Glances + """Main entry point for Glances. Select the mode (standalone, client or server) Run it... diff --git a/glances/core/glances_client.py b/glances/core/glances_client.py index b2773c50..d2b05d97 100644 --- a/glances/core/glances_client.py +++ b/glances/core/glances_client.py @@ -16,9 +16,8 @@ # # You should have received a copy of the GNU Lesser General Public License # along with this program. If not, see . -""" -Manage the Glances' client -""" + +"""Manage the Glances client.""" # Import system libs import json @@ -30,15 +29,14 @@ except ImportError: # Python 2 from xmlrpclib import ServerProxy, ProtocolError # Import Glances libs -from glances.core.glances_globals import __version__ +from glances.core.glances_globals import version from glances.core.glances_stats import GlancesStatsClient -from glances.outputs.glances_curses import glancesCurses +from glances.outputs.glances_curses import GlancesCurses -class GlancesClient(): - """ - This class creates and manages the TCP client - """ +class GlancesClient(object): + + """This class creates and manages the TCP client.""" def __init__(self, config=None, args=None): # Store the arg/config @@ -63,8 +61,8 @@ class GlancesClient(): sys.exit(2) def set_mode(self, mode='glances'): - """ - Set the client mode + """Set the client mode. + - 'glances' = Glances server (default) - 'snmp' = SNMP (fallback) """ @@ -72,18 +70,15 @@ class GlancesClient(): return self.mode def get_mode(self): - """ - Return the client mode + """Get the client mode. + - 'glances' = Glances server (default) - 'snmp' = SNMP (fallback) """ return self.mode def login(self): - """ - Logon to the server - """ - + """Logon to the server.""" ret = True # First of all, trying to connect to a Glances server @@ -102,7 +97,7 @@ class GlancesClient(): print(_("Error: Connection to server failed: {0}").format(err)) sys.exit(2) - if self.get_mode() == 'glances' and __version__[:3] == client_version[:3]: + if self.get_mode() == 'glances' and version[:3] == client_version[:3]: # Init stats self.stats = GlancesStatsClient() self.stats.set_plugins(json.loads(self.client.getAllPlugins())) @@ -126,19 +121,13 @@ class GlancesClient(): self.stats.load_limits(self.config) # Init screen - self.screen = glancesCurses(args=self.args) + self.screen = GlancesCurses(args=self.args) # Return result return ret def update(self): - """ - Get stats from server - Return the client/server connection status: - - Connected: Connection OK - - Disconnected: Connection NOK - """ - # Update the stats + """Update stats from Glances/SNMP server.""" if self.get_mode() == 'glances': return self.update_glances() elif self.get_mode() == 'snmp': @@ -148,8 +137,8 @@ class GlancesClient(): sys.exit(2) def update_glances(self): - """ - Get stats from Glances server + """Get stats from Glances server. + Return the client/server connection status: - Connected: Connection OK - Disconnected: Connection NOK @@ -159,7 +148,7 @@ class GlancesClient(): server_stats = json.loads(self.client.getAll()) server_stats['monitor'] = json.loads(self.client.getAllMonitored()) except socket.error: - # Client can not get server stats + # Client cannot get server stats return "Disconnected" else: # Put it in the internal dict @@ -167,8 +156,8 @@ class GlancesClient(): return "Connected" def update_snmp(self): - """ - Get stats from SNMP server + """Get stats from SNMP server. + Return the client/server connection status: - SNMP: Connection with SNMP server OK - Disconnected: Connection NOK @@ -184,9 +173,7 @@ class GlancesClient(): return "SNMP" def serve_forever(self): - """ - Main client loop - """ + """Main client loop.""" while True: # Update the stats cs_status = self.update() @@ -197,8 +184,5 @@ class GlancesClient(): # print self.stats.getAll() def end(self): - """ - End of the client session - """ + """End of the client session.""" self.screen.end() - diff --git a/glances/core/glances_config.py b/glances/core/glances_config.py index b1f85c1c..6db373ea 100644 --- a/glances/core/glances_config.py +++ b/glances/core/glances_config.py @@ -17,6 +17,8 @@ # You should have received a copy of the GNU Lesser General Public License # along with this program. If not, see . +"""Manage the configuration file.""" + # Import system libs import os import sys @@ -29,7 +31,7 @@ except ImportError: # Python 2 # Import Glances lib from glances.core.glances_globals import ( - __appname__, + appname, is_bsd, is_linux, is_mac, @@ -41,8 +43,8 @@ from glances.core.glances_globals import ( class Config(object): - """ - This class is used to access/read config file, if it exists + + """This class is used to access/read config file, if it exists. :param location: the custom path to search for config file :type location: str or None @@ -56,9 +58,7 @@ class Config(object): self.load() def load(self): - """ - Load a config file from the list of paths, if it exists - """ + """Load a config file from the list of paths, if it exists.""" for config_file in self.get_config_paths(): if os.path.isfile(config_file) and os.path.getsize(config_file) > 0: try: @@ -73,9 +73,9 @@ class Config(object): break def get_config_paths(self): - """ - Get a list of config file paths, taking into account of the OS, - priority and location. + r"""Get a list of config file paths. + + The list is built taking into account of the OS, priority and location. * running from source: /path/to/glances/conf * Linux: ~/.config/glances, /etc/glances @@ -101,39 +101,33 @@ class Config(object): if is_linux or is_bsd: paths.append(os.path.join( os.environ.get('XDG_CONFIG_HOME') or os.path.expanduser('~/.config'), - __appname__, self.config_filename)) + appname, self.config_filename)) if hasattr(sys, 'real_prefix') or is_bsd: - paths.append(os.path.join(sys.prefix, 'etc', __appname__, self.config_filename)) + paths.append(os.path.join(sys.prefix, 'etc', appname, self.config_filename)) else: - paths.append(os.path.join('/etc', __appname__, self.config_filename)) + paths.append(os.path.join('/etc', appname, self.config_filename)) elif is_mac: paths.append(os.path.join( os.path.expanduser('~/Library/Application Support/'), - __appname__, self.config_filename)) + appname, self.config_filename)) paths.append(os.path.join( - sys_prefix, 'etc', __appname__, self.config_filename)) + sys_prefix, 'etc', appname, self.config_filename)) elif is_windows: paths.append(os.path.join( - os.environ.get('APPDATA'), __appname__, self.config_filename)) + os.environ.get('APPDATA'), appname, self.config_filename)) return paths def items(self, section): - """ - Return the items list of a section - """ + """Return the items list of a section.""" return self.parser.items(section) def has_section(self, section): - """ - Return info about the existence of a section - """ + """Return info about the existence of a section.""" return self.parser.has_section(section) def get_option(self, section, option): - """ - Get the float value of an option, if it exists - """ + """Get the float value of an option, if it exists.""" try: value = self.parser.getfloat(section, option) except NoOptionError: @@ -142,9 +136,7 @@ class Config(object): return value def get_raw_option(self, section, option): - """ - Get the raw value of an option, if it exists - """ + """Get the raw value of an option, if it exists.""" try: value = self.parser.get(section, option) except NoOptionError: diff --git a/glances/core/glances_globals.py b/glances/core/glances_globals.py index bebb31fb..3601adb9 100644 --- a/glances/core/glances_globals.py +++ b/glances/core/glances_globals.py @@ -17,30 +17,15 @@ # You should have received a copy of the GNU Lesser General Public License # along with this program. If not, see . -# Glances informations -__appname__ = 'glances' -__version__ = '2.0_RC4' -__author__ = 'Nicolas Hennion ' -__license__ = 'LGPL' +"""Common objects shared by all Glances modules.""" -# Import system libs import os import sys -# Import psutil -try: - from psutil import __version__ as __psutil_version__ -except ImportError: - print('psutil library not found. Glances cannot start.') - sys.exit(1) - -# Check psutil version -psutil_min_version = (2, 0, 0) -psutil_version = tuple([int(num) for num in __psutil_version__.split('.')]) -if psutil_version < psutil_min_version: - print('psutil version {0} detected.').format(__psutil_version__) - print('psutil 2.0 or higher is needed. Glances cannot start.') - sys.exit(1) +# Global information +appname = 'glances' +version = __import__('glances').__version__ +psutil_version = __import__('glances').__psutil_version # PY3? is_py3 = sys.version_info >= (3, 3) @@ -63,7 +48,7 @@ sys_path = sys.path[:] sys.path.insert(0, plugins_path) # i18n -gettext_domain = __appname__ +gettext_domain = appname i18n_path = os.path.realpath(os.path.join(work_path, '..', '..', 'i18n')) sys_i18n_path = os.path.join(sys_prefix, 'share', 'locale') if os.path.exists(i18n_path): @@ -73,13 +58,13 @@ elif os.path.exists(sys_i18n_path): else: locale_dir = None -# Instances shared between all Glances' scripts -# =============================================== +# Instances shared between all Glances scripts +# ============================================ # glances_processes for processcount and processlist plugins -from glances.core.glances_processes import glancesProcesses -glances_processes = glancesProcesses() +from glances.core.glances_processes import GlancesProcesses +glances_processes = GlancesProcesses() # The global instance for the logs -from glances.core.glances_logs import glancesLogs -glances_logs = glancesLogs() +from glances.core.glances_logs import GlancesLogs +glances_logs = GlancesLogs() diff --git a/glances/core/glances_logs.py b/glances/core/glances_logs.py index 37e3143e..393ef626 100644 --- a/glances/core/glances_logs.py +++ b/glances/core/glances_logs.py @@ -17,6 +17,8 @@ # You should have received a copy of the GNU Lesser General Public License # along with this program. If not, see . +"""Manage logs.""" + # Import system libs import time from datetime import datetime @@ -25,14 +27,15 @@ from datetime import datetime from glances.core.glances_globals import glances_processes -class glancesLogs: - """ - Manage logs inside the Glances software - Logs is a list of list (stored in the self.logs_list var) +class GlancesLogs(object): + """This class manages logs inside the Glances software. + + Logs is a list of list (stored in the self.logs_list var) item_state = "OK|CAREFUL|WARNING|CRITICAL" item_type = "CPU*|LOAD|MEM|MON" item_value = value + Item is defined by: ["begin", "end", @@ -44,10 +47,7 @@ class glancesLogs: """ def __init__(self): - """ - Init the logs class - """ - + """Init the logs class.""" # Maximum size of the logs list self.logs_max = 10 @@ -55,24 +55,20 @@ class glancesLogs: self.logs_list = [] def get(self): - """ - Return the logs list (RAW) - """ + """Return the raw logs list.""" return self.logs_list def len(self): - """ - Return the number of item in the log list - """ + """Return the number of item in the logs list.""" return self.logs_list.__len__() def __itemexist__(self, item_type): - """ + """Return the item position, if it exists. + An item exist in the list if: * end is < 0 * item_type is matching - Return the item position if exist - -1 if the item is not found + Return -1 if the item is not found. """ for i in range(self.len()): if self.logs_list[i][1] < 0 and self.logs_list[i][3] == item_type: @@ -80,9 +76,7 @@ class glancesLogs: return -1 def set_process_sort(self, item_type): - """ - Define the process auto sort key from the alert type - """ + """Define the process auto sort key from the alert type.""" # Process sort depending on alert type if item_type.startswith("MEM"): # Sort TOP process by memory_percent @@ -99,9 +93,7 @@ class glancesLogs: return process_auto_by def reset_process_sort(self): - """ - Reset the process_auto_by variable - """ + """Reset the process_auto_by variable.""" # Default sort is... process_auto_by = 'cpu_percent' @@ -110,11 +102,11 @@ class glancesLogs: return process_auto_by def add(self, item_state, item_type, item_value, proc_list=[], proc_desc=""): - """ - If item is a 'new one': - Add the new item at the beginning of the logs list - Else: - Update the existing item + """Add a new item to the logs list. + + If 'item' is a 'new one', add the new item at the beginning of the logs + list. + If 'item' is not a 'new one', update the existing item. """ # Add or update the log item_index = self.__itemexist__(item_type) @@ -190,8 +182,8 @@ class glancesLogs: return self.len() def clean(self, critical=False): - """ - Clean the log list by deleting finished item + """Clean the logs list by deleting finished items. + By default, only delete WARNING message If critical = True, also delete CRITICAL message """ diff --git a/glances/core/glances_main.py b/glances/core/glances_main.py index 8866a460..4d866b2d 100644 --- a/glances/core/glances_main.py +++ b/glances/core/glances_main.py @@ -16,26 +16,20 @@ # # You should have received a copy of the GNU Lesser General Public License # along with this program. If not, see . -""" -Main Glances script -""" + +"""Glances main class.""" # Import system libs import argparse # Import Glances libs from glances.core.glances_config import Config -from glances.core.glances_globals import ( - __appname__, - __psutil_version__, - __version__ -) +from glances.core.glances_globals import appname, psutil_version, version class GlancesMain(object): - """ - Main class to manage Glances instance - """ + + """Main class to manage Glances instance.""" # Default stats' refresh time is 3 seconds refresh_time = 3 @@ -58,9 +52,9 @@ class GlancesMain(object): def init_args(self): """Init all the command line arguments.""" - version = "Glances v" + __version__ + " with psutil v" + __psutil_version__ - parser = argparse.ArgumentParser(prog=__appname__, conflict_handler='resolve') - parser.add_argument('-V', '--version', action='version', version=version) + _version = "Glances v" + version + " with psutil v" + psutil_version + parser = argparse.ArgumentParser(prog=appname, conflict_handler='resolve') + parser.add_argument('-V', '--version', action='version', version=_version) parser.add_argument('-b', '--byte', action='store_true', default=False, dest='byte', help=_('display network rate in byte per second')) parser.add_argument('-B', '--bind', default='0.0.0.0', dest='bind_address', @@ -161,7 +155,6 @@ class GlancesMain(object): self.server_ip = args.client # /!!! - # Interactive cmds like CLI args? # By default help is hidden args.help_tag = False @@ -172,59 +165,45 @@ class GlancesMain(object): return args def __hash_password(self, plain_password): - """ - Hash a plain password and return the hashed one - """ - from glances.core.glances_password import glancesPassword + """Hash a plain password and return the hashed one.""" + from glances.core.glances_password import GlancesPassword - password = glancesPassword() + password = GlancesPassword() return password.hash_password(plain_password) def __get_password(self, description='', confirm=False, clear=False): - """ - Read a password from the command line - - with confirmation if confirm = True - - plain (clear password) if clear = True - """ - from glances.core.glances_password import glancesPassword + """Read a password from the command line. - password = glancesPassword() + - if confirm = True, with confirmation + - if clear = True, plain (clear password) + """ + from glances.core.glances_password import GlancesPassword + + password = GlancesPassword() return password.get_password(description, confirm, clear) def is_standalone(self): - """ - Return True if Glances is running in standalone mode - """ + """Return True if Glances is running in standalone mode.""" return not self.client_tag and not self.server_tag and not self.webserver_tag def is_client(self): - """ - Return True if Glances is running in client mode - """ + """Return True if Glances is running in client mode.""" return self.client_tag and not self.server_tag def is_server(self): - """ - Return True if Glances is running in server mode - """ + """Return True if Glances is running in server mode.""" return not self.client_tag and self.server_tag def is_webserver(self): - """ - Return True if Glances is running in Web server mode - """ + """Return True if Glances is running in Web server mode.""" return not self.client_tag and self.webserver_tag def get_config(self): - """ - Return configuration file object - """ + """Return configuration file object.""" return self.config def get_args(self): - """ - Return the arguments - """ + """Return the arguments.""" return self.args diff --git a/glances/core/glances_monitor_list.py b/glances/core/glances_monitor_list.py index 4de6fcf0..d3329407 100644 --- a/glances/core/glances_monitor_list.py +++ b/glances/core/glances_monitor_list.py @@ -17,6 +17,8 @@ # You should have received a copy of the GNU Lesser General Public License # along with this program. If not, see . +"""Manage the monitor list.""" + # Import system lib import re import subprocess @@ -25,41 +27,40 @@ import subprocess from glances.core.glances_globals import glances_processes -class monitorList: - """ - This class describes the optionnal monitored processes list - A list of 'important' processes to monitor. +class MonitorList(object): - The list (Python list) is composed of items (Python dict) - An item is defined (Dict keys'): + """This class describes the optional monitored processes list. + + The monitored list is a list of 'important' processes to monitor. + + The list (Python list) is composed of items (Python dict). + An item is defined (dict keys): * description: Description of the processes (max 16 chars) * regex: regular expression of the processes to monitor * command: (optional) shell command for extended stat * countmin: (optional) minimal number of processes * countmax: (optional) maximum number of processes """ + # Maximum number of items in the list __monitor_list_max_size = 10 # The list __monitor_list = [] def __init__(self, config): - """ - Init the monitoring list from the configuration file - """ - + """Init the monitoring list from the configuration file.""" self.config = config if self.config is not None and self.config.has_section('monitor'): # Process monitoring list - self.__setMonitorList('monitor', 'list') + self.__set_monitor_list('monitor', 'list') else: self.__monitor_list = [] - def __setMonitorList(self, section, key): - """ - Init the monitored processes list - The list is defined in the Glances configuration file + def __set_monitor_list(self, section, key): + """Init the monitored processes list. + + The list is defined in the Glances configuration file. """ for l in range(1, self.__monitor_list_max_size + 1): value = {} @@ -99,9 +100,9 @@ class monitorList: return len(self.__monitor_list) def __get__(self, item, key): - """ - Meta function to return key value of item - None if not defined or item > len(list) + """Meta function to return key value of item. + + Return None if not defined or item > len(list) """ if item < len(self.__monitor_list): try: @@ -112,15 +113,12 @@ class monitorList: return None def update(self): - """ - Update the command result attributed - """ - + """Update the command result attributed.""" # Only continue if monitor list is not empty if len(self.__monitor_list) == 0: return self.__monitor_list - # Iter uppon the monitored list + # Iter upon the monitored list for i in range(0, len(self.get())): # Search monitored processes by a regular expression processlist = glances_processes.getlist() @@ -147,15 +145,11 @@ class monitorList: return self.__monitor_list def get(self): - """ - Return the monitored list (list of dict) - """ + """Return the monitored list (list of dict).""" return self.__monitor_list def set(self, newlist): - """ - Set the monitored list (list of dict) - """ + """Set the monitored list (list of dict).""" self.__monitor_list = newlist def getAll(self): @@ -167,37 +161,25 @@ class monitorList: self.set(newlist) def description(self, item): - """ - Return the description of the item number (item) - """ + """Return the description of the item number (item).""" return self.__get__(item, "description") def regex(self, item): - """ - Return the regular expression of the item number (item) - """ + """Return the regular expression of the item number (item).""" return self.__get__(item, "regex") def command(self, item): - """ - Return the stats command of the item number (item) - """ + """Return the stat command of the item number (item).""" return self.__get__(item, "command") def result(self, item): - """ - Return the reult command of the item number (item) - """ + """Return the reult command of the item number (item).""" return self.__get__(item, "result") def countmin(self, item): - """ - Return the minimum number of processes of the item number (item) - """ + """Return the minimum number of processes of the item number (item).""" return self.__get__(item, "countmin") def countmax(self, item): - """ - Return the maximum number of processes of the item number (item) - """ + """Return the maximum number of processes of the item number (item).""" return self.__get__(item, "countmax") diff --git a/glances/core/glances_password.py b/glances/core/glances_password.py index 4e03af89..b1a906be 100644 --- a/glances/core/glances_password.py +++ b/glances/core/glances_password.py @@ -17,6 +17,8 @@ # You should have received a copy of the GNU Lesser General Public License # along with this program. If not, see . +"""Manage password.""" + # Import system libs import getpass import hashlib @@ -26,7 +28,7 @@ import uuid # Import Glances lib from glances.core.glances_globals import ( - __appname__, + appname, is_bsd, is_linux, is_mac, @@ -40,10 +42,9 @@ except NameError: pass -class glancesPassword: - """ - Manage password - """ +class GlancesPassword(object): + + """This class contains all the methods relating to password.""" def __init__(self): self.password_path = self.get_password_path() @@ -51,8 +52,8 @@ class glancesPassword: self.password_filepath = os.path.join(self.password_path, self.password_filename) def get_password_path(self): - """ - Get the path where the password file will be stored + r"""Get the path where the password file will be stored. + * Linux and BSD: ~/.config/glances * OS X: ~/Library/glances * Windows: %APPDATA%\glances @@ -67,45 +68,42 @@ class glancesPassword: app_path = '.' # Append the Glances folder - app_path = os.path.join(app_path, __appname__) + app_path = os.path.join(app_path, appname) return app_path def get_hash(self, salt, plain_password): - """ - Return the hashed password salt + SHA-256 - """ + """Return the hashed password, salt + SHA-256.""" return hashlib.sha256(salt.encode() + plain_password.encode()).hexdigest() def hash_password(self, plain_password): - """ - Hash password with a salt based on UUID (universally unique identifier) - """ + """Hash password with a salt based on UUID (universally unique identifier).""" salt = uuid.uuid4().hex encrypted_password = self.get_hash(salt, plain_password) return salt + '$' + encrypted_password def check_password(self, hashed_password, plain_password): - """ - Encode the plain_password with the salt of the hashed_password - and return the comparison with the encrypted_password + """Encode the plain_password with the salt of the hashed_password. + + Return the comparison with the encrypted_password. """ salt, encrypted_password = hashed_password.split('$') re_encrypted_password = self.get_hash(salt, plain_password) return encrypted_password == re_encrypted_password def get_password(self, description='', confirm=False, clear=False): - """ - For Glances server, get the password (confirm=True, clear=False) - 1) from the password file (if it exists) - 2) from the CLI + """Get the password from a Glances client or server. + + For Glances server, get the password (confirm=True, clear=False): + 1) from the password file (if it exists) + 2) from the CLI Optionally: save the password to a file (hashed with salt + SHA-256) - For Glances client, get the password (confirm=False, clear=True) - 1) from the CLI - 2) the password is hashed with SHA-256 (only SHA string transit through the network) + For Glances client, get the password (confirm=False, clear=True): + 1) from the CLI + 2) the password is hashed with SHA-256 (only SHA string transit + through the network) """ - if os.path.exists(self.password_filepath) and not clear: # If the password file exist then use it print(_("Info: Read password from file: {0}").format(self.password_filepath)) @@ -142,9 +140,7 @@ class glancesPassword: return password def save_password(self, hashed_password): - """ - Save the hashed password to the Glances folder - """ + """Save the hashed password to the Glances folder.""" # Check if the Glances folder already exists if not os.path.exists(self.password_path): # Create the Glances folder @@ -159,9 +155,7 @@ class glancesPassword: file_pwd.write(hashed_password) def load_password(self): - """ - Load the hashed password from the Glances folder - """ + """Load the hashed password from the Glances folder.""" # Read the password file, if it exists with open(self.password_filepath, 'r') as file_pwd: hashed_password = file_pwd.read() diff --git a/glances/core/glances_processes.py b/glances/core/glances_processes.py index 48640b56..6c051c56 100644 --- a/glances/core/glances_processes.py +++ b/glances/core/glances_processes.py @@ -17,22 +17,18 @@ # You should have received a copy of the GNU Lesser General Public License # along with this program. If not, see . -import psutil - -# Import Glances lib from glances.core.glances_globals import is_bsd, is_mac, is_windows from glances.core.glances_timer import Timer, getTimeSinceLastUpdate +import psutil -class glancesProcesses: - """ - Get processed stats using the PsUtil lib - """ + +class GlancesProcesses(object): + + """Get processed stats using the psutil library.""" def __init__(self, cache_timeout=60): - """ - Init the class to collect stats about processes - """ + """Init the class to collect stats about processes.""" # Add internals caches because PSUtil do not cache all the stats # See: https://code.google.com/p/psutil/issues/detail?id=462 self.username_cache = {} @@ -57,22 +53,16 @@ class glancesProcesses: self.disable_tag = False def enable(self): - """ - Enable process stats - """ + """Enable process stats.""" self.disable_tag = False self.update() def disable(self): - """ - Enable process stats - """ + """Disable process stats.""" self.disable_tag = True def __get_process_stats(self, proc): - """ - Get process statistics - """ + """Get process stats.""" procstat = {} # Process ID @@ -157,10 +147,7 @@ class glancesProcesses: return procstat def update(self): - """ - Update the processes sats - """ - + """Update the processes stats.""" # Reset the stats self.processlist = [] self.processcount = {'total': 0, 'running': 0, 'sleeping': 0, 'thread': 0} @@ -213,31 +200,24 @@ class glancesProcesses: self.cache_timer.reset() def getcount(self): + """Get the number of processes.""" return self.processcount def getlist(self, sortedby=None): - """ - Return the processlist - """ + """Get the processlist.""" return self.processlist def getsortkey(self): - """ - Return the current sort key for automatic sort - """ + """Get the current sort key for automatic sort.""" return self.processsort def setsortkey(self, sortedby): - """ - Return the current sort key for automatic sort - """ + """Set the current sort key for automatic sort.""" self.processsort = sortedby return self.processsort def getsortlist(self, sortedby=None): - """ - Return the processlist - """ + """Get the sorted processlist.""" if sortedby is None: # No need to sort... return self.processlist diff --git a/glances/core/glances_server.py b/glances/core/glances_server.py index ead8c595..8b7bf349 100644 --- a/glances/core/glances_server.py +++ b/glances/core/glances_server.py @@ -17,6 +17,8 @@ # You should have received a copy of the GNU Lesser General Public License # along with this program. If not, see . +"""Manage the Glances server.""" + # Import system libs import json import socket @@ -30,15 +32,15 @@ except ImportError: # Python 2 from SimpleXMLRPCServer import SimpleXMLRPCServer # Import Glances libs -from glances.core.glances_globals import __version__ +from glances.core.glances_globals import version from glances.core.glances_stats import GlancesStatsServer from glances.core.glances_timer import Timer class GlancesXMLRPCHandler(SimpleXMLRPCRequestHandler): - """ - Main XMLRPC handler - """ + + """Main XML-RPC handler.""" + rpc_paths = ('/RPC2', ) def end_headers(self): @@ -63,24 +65,24 @@ class GlancesXMLRPCHandler(SimpleXMLRPCRequestHandler): # Client authentication (basic, _, encoded) = headers.get('Authorization').partition(' ') assert basic == 'Basic', 'Only basic authentication supported' - # Encoded portion of the header is a string - # Need to convert to bytestring - encodedByteString = encoded.encode() - # Decode Base64 byte String to a decoded Byte String - decodedBytes = b64decode(encodedByteString) - # Convert from byte string to a regular String - decodedString = decodedBytes.decode() - # Get the username and password from the string - (username, _, password) = decodedString.partition(':') - # Check that username and password match internal global dictionary + # Encoded portion of the header is a string + # Need to convert to bytestring + encoded_byte_string = encoded.encode() + # Decode base64 byte string to a decoded byte string + decoded_bytes = b64decode(encoded_byte_string) + # Convert from byte string to a regular string + decoded_string = decoded_bytes.decode() + # Get the username and password from the string + (username, _, password) = decoded_string.partition(':') + # Check that username and password match internal global dictionary return self.check_user(username, password) def check_user(self, username, password): - # Check username and password in the dictionnary + # Check username and password in the dictionary if username in self.server.user_dict: - from glances.core.glances_password import glancesPassword + from glances.core.glances_password import GlancesPassword - pwd = glancesPassword() + pwd = GlancesPassword() return pwd.check_password(self.server.user_dict[username], password) else: @@ -102,9 +104,8 @@ class GlancesXMLRPCHandler(SimpleXMLRPCRequestHandler): class GlancesXMLRPCServer(SimpleXMLRPCServer): - """ - Init a SimpleXMLRPCServer instance (IPv6-ready) - """ + + """Init a SimpleXMLRPCServer instance (IPv6-ready).""" def __init__(self, bind_address, bind_port=61209, requestHandler=GlancesXMLRPCHandler): @@ -119,10 +120,9 @@ class GlancesXMLRPCServer(SimpleXMLRPCServer): requestHandler) -class GlancesInstance(): - """ - All the methods of this class are published as XML RPC methods - """ +class GlancesInstance(object): + + """All the methods of this class are published as XML-RPC methods.""" def __init__(self, cached_time=1, config=None): # Init stats @@ -145,7 +145,7 @@ class GlancesInstance(): def init(self): # Return the Glances version - return __version__ + return version def getAll(self): # Update and return all the stats @@ -166,11 +166,10 @@ class GlancesInstance(): return json.dumps(self.stats.getAll()['monitor']) def __getattr__(self, item): - """ - Overwrite the getattr in case of attribute is not found - The goal is to dynamicaly generate the API get'Stats'() methods - """ + """Overwrite the getattr method in case of attribute is not found. + The goal is to dynamically generate the API get'Stats'() methods. + """ # print "DEBUG: Call method: %s" % item header = 'get' # Check if the attribute starts with 'get' @@ -189,10 +188,9 @@ class GlancesInstance(): raise AttributeError(item) -class GlancesServer(): - """ - This class creates and manages the TCP server - """ +class GlancesServer(object): + + """This class creates and manages the TCP server.""" def __init__(self, requestHandler=GlancesXMLRPCHandler, cached_time=1, @@ -216,23 +214,18 @@ class GlancesServer(): self.server.register_instance(GlancesInstance(cached_time, config)) def add_user(self, username, password): - """ - Add an user to the dictionnary - """ + """Add an user to the dictionary.""" self.server.user_dict[username] = password self.server.isAuth = True def serve_forever(self): - """ - Call the main loop - """ + """Call the main loop.""" self.server.serve_forever() def server_close(self): + """Close the Glances server session.""" self.server.server_close() def end(self): - """ - End of the Glances server session - """ + """End of the Glances server session.""" self.server_close() diff --git a/glances/core/glances_snmp.py b/glances/core/glances_snmp.py index c2014c61..f7b8692a 100644 --- a/glances/core/glances_snmp.py +++ b/glances/core/glances_snmp.py @@ -28,7 +28,8 @@ except ImportError: class GlancesSNMPClient(object): - """ SNMP client class (based on PySNMP) """ + + """SNMP client class (based on pysnmp library).""" def __init__(self, host='localhost', port=161, version='2c', community='public', user='private', auth=''): @@ -46,10 +47,7 @@ class GlancesSNMPClient(object): self.auth = auth def __get_result__(self, errorIndication, errorStatus, errorIndex, varBinds): - """ - Put results in table - """ - + """Put results in table.""" ret = {} if not errorIndication or not errorStatus: for name, val in varBinds: @@ -60,13 +58,13 @@ class GlancesSNMPClient(object): return ret def get_by_oid(self, *oid): - """ - SNMP simple request (list of OID) - One request per OID list + """SNMP simple request (list of OID). + + One request per OID list. + * oid: oid list > Return a dict """ - if self.version == '3': errorIndication, errorStatus, errorIndex, varBinds = self.cmdGen.getCmd( cmdgen.UsmUserData(self.user, self.auth), @@ -95,16 +93,19 @@ class GlancesSNMPClient(object): return ret def getbulk_by_oid(self, non_repeaters, max_repetitions, *oid): - """ - SNMP getbulk request - In contrast to snmpwalk, this information will typically be gathered in a - single transaction with the agent, rather than one transaction per variable found. - * non_repeaters: This specifies the number of supplied variables that should not be iterated over. - * max_repetitions: This specifies the maximum number of iterations over the repeating variables. + """SNMP getbulk request. + + In contrast to snmpwalk, this information will typically be gathered in + a single transaction with the agent, rather than one transaction per + variable found. + + * non_repeaters: This specifies the number of supplied variables that + should not be iterated over. + * max_repetitions: This specifies the maximum number of iterations over + the repeating variables. * oid: oid list > Return a list of dicts """ - if self.version.startswith('3'): errorIndication, errorStatus, errorIndex, varBinds = self.cmdGen.getCmd( cmdgen.UsmUserData(self.user, self.auth), diff --git a/glances/core/glances_standalone.py b/glances/core/glances_standalone.py index 2c89d537..05e770ab 100644 --- a/glances/core/glances_standalone.py +++ b/glances/core/glances_standalone.py @@ -17,18 +17,18 @@ # You should have received a copy of the GNU Lesser General Public License # along with this program. If not, see . +"""Manage the Glances standalone session.""" + # Import Glances libs from glances.core.glances_stats import GlancesStats -from glances.outputs.glances_curses import glancesCurses +from glances.outputs.glances_curses import GlancesCurses -class GlancesStandalone(): - """ - This class creates and manages the Glances standalone session - """ +class GlancesStandalone(object): + + """This class creates and manages the Glances standalone session.""" def __init__(self, config=None, args=None): - # Init stats self.stats = GlancesStats(config) @@ -37,20 +37,18 @@ class GlancesStandalone(): # Init CSV output if args.output_csv is not None: - from glances.outputs.glances_csv import glancesCSV + from glances.outputs.glances_csv import GlancesCSV - self.csvoutput = glancesCSV(args=args) + self.csvoutput = GlancesCSV(args=args) self.csv_tag = True else: self.csv_tag = False # Init screen - self.screen = glancesCurses(args=args) + self.screen = GlancesCurses(args=args) def serve_forever(self): - """ - Main loop for the CLI - """ + """Main loop for the CLI.""" while True: # Update system informations self.stats.update() @@ -63,9 +61,7 @@ class GlancesStandalone(): self.csvoutput.update(self.stats) def end(self): - """ - End of the CLI - """ + """End of the CLI.""" self.screen.end() # Close the CSV file diff --git a/glances/core/glances_stats.py b/glances/core/glances_stats.py index 0e6961ee..4f265e06 100644 --- a/glances/core/glances_stats.py +++ b/glances/core/glances_stats.py @@ -17,6 +17,8 @@ # You should have received a copy of the GNU Lesser General Public License # along with this program. If not, see . +"""The stats manager.""" + import collections import os import sys @@ -25,15 +27,10 @@ from glances.core.glances_globals import plugins_path, sys_path class GlancesStats(object): - """ - This class store, update and give stats - """ + + """This class stores, updates and gives stats.""" def __init__(self, config=None): - """ - Init the stats - """ - # Init the plugin list dict self._plugins = collections.defaultdict(dict) @@ -44,12 +41,11 @@ class GlancesStats(object): self.load_limits(config) def __getattr__(self, item): - """ - Overwrite the getattr in case of attribute is not found + """Overwrite the getattr method in case of attribute is not found. + The goal is to dynamically generate the following methods: - getPlugname(): return Plugname stat in JSON format """ - # Check if the attribute starts with 'get' if item.startswith('get'): # Get the plugin name @@ -67,9 +63,7 @@ class GlancesStats(object): raise AttributeError(item) def load_plugins(self, args=None): - """ - Load all plugins in the "plugins" folder - """ + """Load all plugins in the 'plugins' folder.""" header = "glances_" for item in os.listdir(plugins_path): if (item.startswith(header) and @@ -87,26 +81,18 @@ class GlancesStats(object): sys.path = sys_path def getAllPlugins(self): - """ - Return the plugins list - """ + """Return the plugins list.""" return [p for p in self._plugins] def load_limits(self, config=None): - """ - Load the stats limits - """ - + """Load the stats limits.""" # For each plugins, call the init_limits method for p in self._plugins: # print "DEBUG: Load limits for %s" % p self._plugins[p].load_limits(config) def __update__(self, input_stats): - """ - Update the stats - """ - + """Update all the stats.""" if input_stats == {}: # For standalone and server modes # For each plugins, call the update method @@ -120,21 +106,19 @@ class GlancesStats(object): self._plugins[p].set_stats(input_stats[p]) def update(self, input_stats={}): - # Update the stats + """Wrapper method to update the stats.""" self.__update__(input_stats) def getAll(self): - """ - Return all the stats - """ + """Return all the stats.""" return [self._plugins[p].get_raw() for p in self._plugins] def get_plugin_list(self): - # Return the plugin list + """Return the plugin list.""" self._plugins def get_plugin(self, plugin_name): - # Return the plugin name + """Return the plugin name.""" if plugin_name in self._plugins: return self._plugins[plugin_name] else: @@ -142,9 +126,8 @@ class GlancesStats(object): class GlancesStatsServer(GlancesStats): - """ - This class store, update and give stats for the server - """ + + """This class stores, updates and gives stats for the server.""" def __init__(self, config=None): # Init the stats @@ -155,11 +138,7 @@ class GlancesStatsServer(GlancesStats): self.all_stats = collections.defaultdict(dict) def update(self, input_stats={}): - """ - Update the stats - """ - - # Update the stats + """Update the stats.""" GlancesStats.update(self) # Build the all_stats with the get_raw() method of the plugins @@ -167,37 +146,29 @@ class GlancesStatsServer(GlancesStats): self.all_stats[p] = self._plugins[p].get_raw() def getAll(self): - """ - Return the stats as a dict - """ + """Return the stats as a dict.""" return self.all_stats def getAllPlugins(self): - """ - Return the plugins list - """ + """Return the plugins list.""" return [p for p in self._plugins] def getAllLimits(self): - """ - Return the plugins limits list - """ + """Return the plugins limits list.""" return [self._plugins[p].get_limits() for p in self._plugins] class GlancesStatsClient(GlancesStats): - """ - This class store, update and give stats for the client - """ + + """This class stores, updates and gives stats for the client.""" def __init__(self): + """Init the GlancesStatsClient class.""" # Init the plugin list dict self._plugins = collections.defaultdict(dict) def set_plugins(self, input_plugins): - """ - Set the plugin list according to the Glances server - """ + """Set the plugin list according to the Glances server.""" header = "glances_" for item in input_plugins: # Import the plugin @@ -213,9 +184,8 @@ class GlancesStatsClient(GlancesStats): class GlancesStatsClientSNMP(GlancesStats): - """ - This class store, update and give stats for the SNMP client - """ + + """This class stores, updates and gives stats for the SNMP client.""" def __init__(self, config=None, args=None): # Init the plugin list dict @@ -231,10 +201,7 @@ class GlancesStatsClientSNMP(GlancesStats): self.load_plugins(args=self.args) def check_snmp(self): - """ - Chek if SNMP is available on the server - """ - + """Chek if SNMP is available on the server.""" # Import the SNMP client class from glances.core.glances_snmp import GlancesSNMPClient @@ -249,10 +216,7 @@ class GlancesStatsClientSNMP(GlancesStats): return clientsnmp.get_by_oid("1.3.6.1.2.1.1.5.0") != {} def update(self): - """ - Update the stats using SNMP - """ - + """Update the stats using SNMP.""" # For each plugins, call the update method for p in self._plugins: # Set the input method to SNMP diff --git a/glances/core/glances_timer.py b/glances/core/glances_timer.py index ce9ce4ef..8b21d8d4 100644 --- a/glances/core/glances_timer.py +++ b/glances/core/glances_timer.py @@ -17,6 +17,8 @@ # You should have received a copy of the GNU Lesser General Public License # along with this program. If not, see . +"""The timer manager.""" + from time import time # Global list to manage the elapsed time @@ -24,6 +26,7 @@ last_update_times = {} def getTimeSinceLastUpdate(IOType): + """Return the elapsed time since last update.""" global last_update_times # assert(IOType in ['net', 'disk', 'process_disk']) current_time = time() @@ -36,11 +39,9 @@ def getTimeSinceLastUpdate(IOType): return time_since_update -class Timer: - """ - The timer class - A simple chrono - """ +class Timer(object): + + """The timer class. A simple chronometer.""" def __init__(self, duration): self.duration = duration @@ -57,4 +58,3 @@ class Timer: def finished(self): return time() > self.target - diff --git a/glances/core/glances_webserver.py b/glances/core/glances_webserver.py index 6c134feb..46d73505 100644 --- a/glances/core/glances_webserver.py +++ b/glances/core/glances_webserver.py @@ -16,22 +16,19 @@ # # You should have received a copy of the GNU Lesser General Public License # along with this program. If not, see . -""" -Glances Web Interface (Bottle based) -""" + +"""Glances Web Interface (Bottle based).""" # Import Glances libs from glances.core.glances_stats import GlancesStats -from glances.outputs.glances_bottle import glancesBottle +from glances.outputs.glances_bottle import GlancesBottle -class GlancesWebServer(): - """ - This class creates and manages the Glances Web Server session - """ +class GlancesWebServer(object): + + """This class creates and manages the Glances Web server session.""" def __init__(self, config=None, args=None): - # Init stats self.stats = GlancesStats(config) @@ -39,16 +36,12 @@ class GlancesWebServer(): self.stats.update() # Init the Bottle Web server - self.web = glancesBottle(args=args) + self.web = GlancesBottle(args=args) def serve_forever(self): - """ - Main loop for the Web Server - """ + """Main loop for the Web server.""" self.web.start(self.stats) def end(self): - """ - End of the Web Server - """ + """End of the Web server.""" self.web.end() diff --git a/glances/outputs/glances_bottle.py b/glances/outputs/glances_bottle.py index fe5ea208..fb3c7570 100644 --- a/glances/outputs/glances_bottle.py +++ b/glances/outputs/glances_bottle.py @@ -17,6 +17,8 @@ # You should have received a copy of the GNU Lesser General Public License # along with this program. If not, see . +"""Web interface class.""" + import os import sys @@ -27,13 +29,11 @@ except ImportError: sys.exit(1) -class glancesBottle: - """ - This class manage the Bottle Web Server - """ +class GlancesBottle(object): + + """This class manages the Bottle Web server.""" def __init__(self, args=None): - # Init args self.args = args @@ -72,29 +72,25 @@ class glancesBottle: } def _route(self): - """ - Define route - """ + """Define route.""" self._app.route('/', method="GET", callback=self._index) self._app.route('/', method=["GET", "POST"], callback=self._index) self._app.route('/', method="GET", callback=self._css) self._app.route('/', method="GET", callback=self._js) def start(self, stats): + """Start the bottle.""" # Init stats self.stats = stats - # Start the Bottle self._app.run(host=self.args.bind_address, port=self.args.port) def end(self): - # End the Bottle + """End the bottle.""" pass def _index(self, refresh_time=None): - """ - Bottle callback for index.html (/) file - """ + """Bottle callback for index.html (/) file.""" # Manage parameter if refresh_time is None: refresh_time = self.args.time @@ -106,26 +102,20 @@ class glancesBottle: return self.display(self.stats, refresh_time=refresh_time) def _css(self, filename): - """ - Bottle callback for *.css files - """ + """Bottle callback for *.css files.""" # Return the static file return static_file(filename, root=os.path.join(self.STATIC_PATH, 'css')) def _js(self, filename): - """ - Bottle callback for *.js files - """ + """Bottle callback for *.js files.""" # Return the static file return static_file(filename, root=os.path.join(self.STATIC_PATH, 'js')) def display(self, stats, refresh_time=None): - """ - Display stats on the Webpage + """Display stats on the web page. stats: Stats database to display """ - html = template('header', refresh_time=refresh_time) html += '
' html += self.display_plugin('system', self.stats.get_plugin('system').get_stats_display(args=self.args)) @@ -163,10 +153,7 @@ class glancesBottle: return html def display_plugin(self, plugin_name, plugin_stats): - """ - Generate the Bootle template for the plugin_stats - """ - + """Generate the Bottle template for the plugin_stats.""" # Template header tpl = """ \ %#Template for Bottle @@ -186,7 +173,7 @@ class glancesBottle: if m['msg'].split(' ', 1)[0] != '': tpl += ' %s' % \ (self.__style_list[m['decoration']], - m['msg'].split(' ', 1)[0].replace(' ', ' ')[:20]) + m['msg'].split(' ', 1)[0].replace(' ', ' ')[:20]) elif m['optional']: # Manage optional stats (responsive design) tpl += '%s' % \ diff --git a/glances/outputs/glances_colorconsole.py b/glances/outputs/glances_colorconsole.py index 20d9b1ae..f61f66a2 100644 --- a/glances/outputs/glances_colorconsole.py +++ b/glances/outputs/glances_colorconsole.py @@ -59,7 +59,7 @@ class ListenGetch(threading.Thread): return default -class Screen(): +class Screen(object): COLOR_DEFAULT_WIN = '0F' # 07'#'0F' COLOR_BK_DEFAULT = colorconsole.terminal.colors["BLACK"] @@ -116,7 +116,7 @@ class Screen(): return None -class WCurseLight(): +class WCurseLight(object): COLOR_WHITE = colorconsole.terminal.colors["WHITE"] COLOR_RED = colorconsole.terminal.colors["RED"] diff --git a/glances/outputs/glances_csv.py b/glances/outputs/glances_csv.py index ae17e267..ff378fb4 100644 --- a/glances/outputs/glances_csv.py +++ b/glances/outputs/glances_csv.py @@ -17,6 +17,8 @@ # You should have received a copy of the GNU Lesser General Public License # along with this program. If not, see . +"""CSV interface class.""" + # Import sys libs import csv import sys @@ -28,10 +30,9 @@ from glances.core.glances_globals import is_py3 csv_stats_list = ['cpu', 'load', 'mem', 'memswap'] -class glancesCSV: - """ - This class manages the CSV output - """ +class GlancesCSV(object): + + """This class manages the CSV output.""" def __init__(self, args=None): # CSV file name @@ -51,12 +52,11 @@ class glancesCSV: print(_("Stats dumped to CSV file: {0}").format(self.csv_filename)) def exit(self): + """Close the CSV file.""" self.csv_file.close() def update(self, stats): - """ - Update stats in the CSV output file - """ + """Update stats in the CSV output file.""" all_stats = stats.getAll() plugins = stats.getAllPlugins() diff --git a/glances/outputs/glances_curses.py b/glances/outputs/glances_curses.py index a07f32b3..34355e3e 100644 --- a/glances/outputs/glances_curses.py +++ b/glances/outputs/glances_curses.py @@ -17,6 +17,8 @@ # You should have received a copy of the GNU Lesser General Public License # along with this program. If not, see . +"""Curses interface class.""" + # Import system lib import sys @@ -37,13 +39,11 @@ else: curses = WCurseLight() -class glancesCurses: - """ - This class manage the curses display (and key pressed) - """ +class GlancesCurses(object): + + """This class manages the curses display (and key pressed).""" def __init__(self, args=None): - # Init args self.args = args @@ -160,10 +160,8 @@ class glancesCurses: self.term_window.nodelay(1) self.pressedkey = -1 - def __getkey(self, window): - """ - A getKey function to catch ESC key AND Numlock key (issue #163) - """ + def __get_key(self, window): + # Catch ESC key AND numlock key (issue #163) keycode = [0, 0] keycode[0] = window.getch() keycode[1] = window.getch() @@ -174,10 +172,10 @@ class glancesCurses: else: return keycode[0] - def __catchKey(self): - # Get key - #~ self.pressedkey = self.term_window.getch() - self.pressedkey = self.__getkey(self.term_window) + def __catch_key(self): + # Catch the pressed key + # ~ self.pressedkey = self.term_window.getch() + self.pressedkey = self.__get_key(self.term_window) # Actions... if self.pressedkey == ord('\x1b') or self.pressedkey == ord('q'): @@ -249,15 +247,14 @@ class glancesCurses: return self.pressedkey def end(self): - # Shutdown the curses window + """Shutdown the curses window.""" curses.echo() curses.nocbreak() curses.curs_set(1) curses.endwin() def display(self, stats, cs_status="None"): - """ - Display stats on the screen + """Display stats on the screen. stats: Stats database to display cs_status: @@ -270,7 +267,6 @@ class glancesCurses: True if the stats have been displayed False if the help have been displayed """ - # Init the internal line/column dict for Glances Curses self.line_to_y = {} self.column_to_x = {} @@ -346,9 +342,9 @@ class glancesCurses: return True def display_plugin(self, plugin_stats, display_optional=True, max_y=65535): - """ - Display the plugin_stats on the screen - If display_optional=True display the optional stats + """Display the plugin_stats on the screen. + + If display_optional=True display the optional stats. max_y do not display line > max_y """ # Exit if: @@ -425,12 +421,12 @@ class glancesCurses: self.line_to_y[plugin_stats['line'] + 1] = y + self.space_between_line def erase(self): - # Erase the content of the screen + """Erase the content of the screen.""" self.term_window.erase() def flush(self, stats, cs_status="None"): - """ - Clear and update screen + """Clear and update the screen. + stats: Stats database to display cs_status: "None": standalone or server mode @@ -441,8 +437,10 @@ class glancesCurses: self.display(stats, cs_status=cs_status) def update(self, stats, cs_status="None"): - """ - Update the screen and wait __refresh_time sec / catch key every 100 ms + """Update the screen. + + Wait for __refresh_time sec / catch key every 100 ms. + stats: Stats database to display cs_status: "None": standalone or server mode @@ -454,18 +452,19 @@ class glancesCurses: # Wait countdown = Timer(self.__refresh_time) - while (not countdown.finished()): + while not countdown.finished(): # Getkey - if self.__catchKey() > -1: + if self.__catch_key() > -1: # flush display self.flush(stats, cs_status=cs_status) # Wait 100ms... curses.napms(100) def get_stats_display_width(self, curse_msg, without_option=False): - # Return the width of the formated curses message - # The height is defined by the maximum line + """Return the width of the formatted curses message. + The height is defined by the maximum line. + """ try: if without_option: # Size without options @@ -481,9 +480,10 @@ class glancesCurses: return c def get_stats_display_height(self, curse_msg): - # Return the height of the formated curses message - # The height is defined by the number of '\n' + r"""Return the height of the formatted curses message. + The height is defined by the number of '\n' (new line). + """ try: c = [i['msg'] for i in curse_msg['msgdict']].count('\n') except: diff --git a/glances/plugins/glances_alert.py b/glances/plugins/glances_alert.py index 377cb996..a334398c 100644 --- a/glances/plugins/glances_alert.py +++ b/glances/plugins/glances_alert.py @@ -17,6 +17,8 @@ # You should have received a copy of the GNU Lesser General Public License # along with this program. If not, see . +"""Alert plugin.""" + # Import system lib from datetime import datetime @@ -26,13 +28,14 @@ from glances.plugins.glances_plugin import GlancesPlugin class Plugin(GlancesPlugin): - """ - Glances's alert Plugin - Only for display + """Glances' alert plugin. + + Only for display. """ def __init__(self, args=None): + """Init the plugin.""" GlancesPlugin.__init__(self, args=args) # We want to display the stat in the curse interface @@ -48,23 +51,16 @@ class Plugin(GlancesPlugin): self.reset() def reset(self): - """ - Reset/init the stats - """ + """Reset/init the stats.""" self.stats = [] def update(self): - """ - Nothing to do here - Just return the global glances_log - """ + """Nothing to do here. Just return the global glances_log.""" # Set the stats to the glances_logs self.stats = glances_logs.get() def msg_curse(self, args=None): - """ - Return the dict to display in the curse interface - """ + """Return the dict to display in the curse interface.""" # Init the return message ret = [] diff --git a/glances/plugins/glances_batpercent.py b/glances/plugins/glances_batpercent.py index c961aa07..d083e78d 100644 --- a/glances/plugins/glances_batpercent.py +++ b/glances/plugins/glances_batpercent.py @@ -16,9 +16,8 @@ # # You should have received a copy of the GNU Lesser General Public License # along with this program. If not, see . -""" -Batinfo (battery) plugin -""" + +"""Battery plugin.""" # Batinfo library (optional; Linux-only) try: @@ -31,17 +30,18 @@ from glances.plugins.glances_plugin import GlancesPlugin class Plugin(GlancesPlugin): - """ - Glances battery capacity plugin + + """Glances' battery capacity plugin. stats is a list """ def __init__(self, args=None): + """Init the plugin.""" GlancesPlugin.__init__(self, args=args) # Init the sensor class - self.glancesgrabbat = glancesGrabBat() + self.glancesgrabbat = GlancesGrabBat() # We do not want to display the stat in a dedicated area # The HDD temp is displayed within the sensors plugin @@ -51,17 +51,11 @@ class Plugin(GlancesPlugin): self.reset() def reset(self): - """ - Reset/init the stats - """ + """Reset/init the stats.""" self.stats = [] def update(self): - - """ - Update battery capacity stats using the input method - """ - + """Update battery capacity stats using the input method.""" # Reset stats self.reset() @@ -78,15 +72,12 @@ class Plugin(GlancesPlugin): return self.stats -class glancesGrabBat: - """ - Get batteries stats using the Batinfo library - """ +class GlancesGrabBat(object): + + """Get batteries stats using the batinfo library.""" def __init__(self): - """ - Init batteries stats - """ + """Init batteries stats.""" try: self.bat = batinfo.batteries() self.initok = True @@ -97,9 +88,7 @@ class glancesGrabBat: self.initok = False def update(self): - """ - Update the stats - """ + """Update the stats.""" if self.initok: reply = self.bat.update() if reply is not None: @@ -111,10 +100,11 @@ class glancesGrabBat: self.bat_list = [] def get(self): - # Update the stats + """Get the stats.""" return self.bat_list def getcapacitypercent(self): + """Get batteries capacity percent.""" if not self.initok or self.bat.stat == []: return [] diff --git a/glances/plugins/glances_core.py b/glances/plugins/glances_core.py index dd147eab..7d9fb321 100644 --- a/glances/plugins/glances_core.py +++ b/glances/plugins/glances_core.py @@ -17,20 +17,24 @@ # You should have received a copy of the GNU Lesser General Public License # along with this program. If not, see . -import psutil +"""CPU core plugin.""" from glances.plugins.glances_plugin import GlancesPlugin +import psutil + class Plugin(GlancesPlugin): - """ - Glances' Core Plugin - Get stats about CPU core number + + """Glances' CPU core plugin. + + Get stats about CPU core number. stats is integer (number of core) """ def __init__(self, args=None): + """Init the plugin.""" GlancesPlugin.__init__(self, args=args) # We dot not want to display the stat in the curse interface @@ -41,17 +45,14 @@ class Plugin(GlancesPlugin): self.reset() def reset(self): - """ - Reset/init the stat using the input method - """ + """Reset/init the stat using the input method.""" self.stats = {} def update(self): - """ - Update core stats - Stats is a dict (with both physical and log cpu number) instead of a integer - """ + """Update core stats. + Stats is a dict (with both physical and log cpu number) instead of a integer. + """ # Reset the stats self.reset() diff --git a/glances/plugins/glances_cpu.py b/glances/plugins/glances_cpu.py index dbf541b6..479e6358 100644 --- a/glances/plugins/glances_cpu.py +++ b/glances/plugins/glances_cpu.py @@ -16,14 +16,13 @@ # # You should have received a copy of the GNU Lesser General Public License # along with this program. If not, see . -""" -Glances CPU plugin -""" -import psutil +"""CPU plugin.""" from glances.plugins.glances_plugin import GlancesPlugin +import psutil + # SNMP OID # percentage of user CPU time: .1.3.6.1.4.1.2021.11.9.0 # percentages of system CPU time: .1.3.6.1.4.1.2021.11.10.0 @@ -34,13 +33,15 @@ snmp_oid = {'user': '1.3.6.1.4.1.2021.11.9.0', class Plugin(GlancesPlugin): + """ - Glances' Cpu Plugin + Glances' CPU plugin. stats is a dict """ def __init__(self, args=None): + """Init the CPU plugin.""" GlancesPlugin.__init__(self, args=args) # We want to display the stat in the curse interface @@ -57,16 +58,11 @@ class Plugin(GlancesPlugin): self.reset() def reset(self): - """ - Reset/init the stats - """ + """Reset/init the stats.""" self.stats = {} def update(self): - """ - Update CPU stats using the input method - """ - + """Update CPU stats using the input method.""" # Reset stats self.reset() @@ -107,10 +103,7 @@ class Plugin(GlancesPlugin): return self.stats def msg_curse(self, args=None): - """ - Return the list to display in the curse interface - """ - + """Return the list to display in the curse interface.""" # Init the return message ret = [] diff --git a/glances/plugins/glances_diskio.py b/glances/plugins/glances_diskio.py index f0c572f6..b42226b4 100644 --- a/glances/plugins/glances_diskio.py +++ b/glances/plugins/glances_diskio.py @@ -16,25 +16,25 @@ # # You should have received a copy of the GNU Lesser General Public License # along with this program. If not, see . -""" -Glances DiskIO plugin -""" -import psutil +"""Disk I/O plugin.""" # Import Glances libs from glances.core.glances_timer import getTimeSinceLastUpdate from glances.plugins.glances_plugin import GlancesPlugin +import psutil + class Plugin(GlancesPlugin): - """ - Glances's disks IO Plugin + + """Glances' disks I/O plugin. stats is a list """ def __init__(self, args=None): + """Init the plugin.""" GlancesPlugin.__init__(self, args=args) # We want to display the stat in the curse interface @@ -50,16 +50,11 @@ class Plugin(GlancesPlugin): self.reset() def reset(self): - """ - Reset/init the stats - """ + """Reset/init the stats.""" self.stats = [] def update(self): - """ - Update disk IO stats using the input method - """ - + """Update disk I/O stats using the input method.""" # Reset stats self.reset() @@ -118,10 +113,7 @@ class Plugin(GlancesPlugin): return self.stats def msg_curse(self, args=None): - """ - Return the dict to display in the curse interface - """ - + """Return the dict to display in the curse interface.""" # Init the return message ret = [] diff --git a/glances/plugins/glances_fs.py b/glances/plugins/glances_fs.py index db41cbcd..c4f7d322 100644 --- a/glances/plugins/glances_fs.py +++ b/glances/plugins/glances_fs.py @@ -17,10 +17,12 @@ # You should have received a copy of the GNU Lesser General Public License # along with this program. If not, see . -import psutil +"""File system plugin.""" from glances.plugins.glances_plugin import GlancesPlugin +import psutil + # SNMP OID # The snmpd.conf needs to be edited. # Add the following to enable it on all disk @@ -43,13 +45,14 @@ snmp_oid = {'mnt_point': '1.3.6.1.4.1.2021.9.1.2', class Plugin(GlancesPlugin): - """ - Glances's File System (fs) Plugin + + """Glances' file system plugin. stats is a list """ def __init__(self, args=None): + """Init the plugin.""" GlancesPlugin.__init__(self, args=args) # We want to display the stat in the curse interface @@ -65,16 +68,11 @@ class Plugin(GlancesPlugin): self.reset() def reset(self): - """ - Reset/init the stats - """ + """Reset/init the stats.""" self.stats = [] def update(self): - """ - Update the FS stats using the input method - """ - + """Update the FS stats using the input method.""" # Reset the list self.reset() @@ -127,9 +125,7 @@ class Plugin(GlancesPlugin): return self.stats def msg_curse(self, args=None): - """ - Return the dict to display in the curse interface - """ + """Return the dict to display in the curse interface.""" # Init the return message ret = [] diff --git a/glances/plugins/glances_hddtemp.py b/glances/plugins/glances_hddtemp.py index 89423b29..87cb1d5e 100644 --- a/glances/plugins/glances_hddtemp.py +++ b/glances/plugins/glances_hddtemp.py @@ -17,6 +17,8 @@ # You should have received a copy of the GNU Lesser General Public License # along with this program. If not, see . +"""HDD temperature plugin.""" + # Import system libs import socket @@ -25,17 +27,18 @@ from glances.plugins.glances_plugin import GlancesPlugin class Plugin(GlancesPlugin): - """ - Glances' HDD temperature sensors plugin + + """Glances' HDD temperature sensors plugin. stats is a list """ def __init__(self, args=None): + """Init the plugin.""" GlancesPlugin.__init__(self, args=args) # Init the sensor class - self.glancesgrabhddtemp = glancesGrabHDDTemp() + self.glancesgrabhddtemp = GlancesGrabHDDTemp() # We do not want to display the stat in a dedicated area # The HDD temp is displayed within the sensors plugin @@ -45,16 +48,11 @@ class Plugin(GlancesPlugin): self.reset() def reset(self): - """ - Reset/init the stats - """ + """Reset/init the stats.""" self.stats = [] def update(self): - """ - Update HDD stats using the input method - """ - + """Update HDD stats using the input method.""" # Reset stats self.reset() @@ -70,25 +68,25 @@ class Plugin(GlancesPlugin): return self.stats -class glancesGrabHDDTemp: - """ - Get hddtemp stats using a socket connection - """ - def __init__(self, host="127.0.0.1", port=7634): - """ - Init hddtemp stats - """ +class GlancesGrabHDDTemp(object): + + """Get hddtemp stats using a socket connection.""" + + def __init__(self, host='127.0.0.1', port=7634): + """Init hddtemp stats.""" self.host = host self.port = port self.cache = "" + self.reset() + + def reset(self): + """Reset/init the stats.""" self.hddtemp_list = [] def __update__(self): - """ - Update the stats - """ + """Update the stats.""" # Reset the list - self.hddtemp_list = [] + self.reset() # Fetch the data data = self.fetch() @@ -118,9 +116,7 @@ class glancesGrabHDDTemp: self.hddtemp_list.append(hddtemp_current) def fetch(self): - """ - Fetch the data from hddtemp daemon - """ + """Fetch the data from hddtemp daemon.""" # Taking care of sudden deaths/stops of hddtemp daemon try: sck = socket.socket(socket.AF_INET, socket.SOCK_STREAM) @@ -133,5 +129,6 @@ class glancesGrabHDDTemp: return data def get(self): + """Get HDDs list.""" self.__update__() return self.hddtemp_list diff --git a/glances/plugins/glances_help.py b/glances/plugins/glances_help.py index 1bbd1a6d..d824f194 100644 --- a/glances/plugins/glances_help.py +++ b/glances/plugins/glances_help.py @@ -16,26 +16,24 @@ # # You should have received a copy of the GNU Lesser General Public License # along with this program. If not, see . + """ -Glances help plugin -Just a stupid plugin to display the help screen +Help plugin. + +Just a stupid plugin to display the help screen. """ # Import Glances libs -from glances.core.glances_globals import ( - __appname__, - __psutil_version__, - __version__ -) +from glances.core.glances_globals import appname, psutil_version, version from glances.plugins.glances_plugin import GlancesPlugin class Plugin(GlancesPlugin): - """ - Glances' Help Plugin - """ + + """Glances' help plugin.""" def __init__(self, args=None): + """Init the plugin.""" GlancesPlugin.__init__(self, args=args) # We want to display the stat in the curse interface @@ -48,24 +46,19 @@ class Plugin(GlancesPlugin): self.line_curse = 0 def update(self): - """ - No stats, it is just a plugin to display the help... - """ + """No stats. It is just a plugin to display the help.""" pass def msg_curse(self, args=None): - """ - Return the list to display in the curse interface - """ - + """Return the list to display in the curse interface.""" # Init the return message ret = [] # Build the string message # Header - msg = '{0} {1}'.format(__appname__.title(), __version__) + msg = '{0} {1}'.format(appname.title(), version) ret.append(self.curse_add_line(msg, "TITLE")) - msg = _(" with psutil {0}").format(__psutil_version__) + msg = _(" with psutil {0}").format(psutil_version) ret.append(self.curse_add_line(msg)) ret.append(self.curse_new_line()) diff --git a/glances/plugins/glances_load.py b/glances/plugins/glances_load.py index 8f7f52bd..4b6a7a14 100644 --- a/glances/plugins/glances_load.py +++ b/glances/plugins/glances_load.py @@ -16,9 +16,8 @@ # # You should have received a copy of the GNU Lesser General Public License # along with this program. If not, see . -""" -Glances load plugin -""" + +"""Load plugin.""" # Import system libs import os @@ -37,13 +36,14 @@ snmp_oid = {'min1': '1.3.6.1.4.1.2021.10.1.3.1', class Plugin(GlancesPlugin): - """ - Glances's Load Plugin + + """Glances' load plugin. stats is a dict """ def __init__(self, args=None): + """Init the plugin.""" GlancesPlugin.__init__(self, args=args) # We want to display the stat in the curse interface @@ -59,16 +59,11 @@ class Plugin(GlancesPlugin): self.reset() def reset(self): - """ - Reset/init the stats - """ + """Reset/init the stats.""" self.stats = {} def update(self): - """ - Update load stats - """ - + """Update load stats.""" # Reset stats self.reset() @@ -107,10 +102,7 @@ class Plugin(GlancesPlugin): return self.stats def msg_curse(self, args=None): - """ - Return the dict to display in the curse interface - """ - + """Return the dict to display in the curse interface.""" # Init the return message ret = [] diff --git a/glances/plugins/glances_mem.py b/glances/plugins/glances_mem.py index b11bdb3a..c89ac343 100644 --- a/glances/plugins/glances_mem.py +++ b/glances/plugins/glances_mem.py @@ -16,14 +16,13 @@ # # You should have received a copy of the GNU Lesser General Public License # along with this program. If not, see . -""" -Glances virtual memory plugin -""" -import psutil +"""Virtual memory plugin.""" from glances.plugins.glances_plugin import GlancesPlugin +import psutil + # SNMP OID # Total RAM in machine: .1.3.6.1.4.1.2021.4.5.0 # Total RAM used: .1.3.6.1.4.1.2021.4.6.0 @@ -40,13 +39,14 @@ snmp_oid = {'total': '1.3.6.1.4.1.2021.4.5.0', class Plugin(GlancesPlugin): - """ - Glances's memory Plugin + + """Glances' memory plugin. stats is a dict """ def __init__(self, args=None): + """Init the plugin.""" GlancesPlugin.__init__(self, args=args) # We want to display the stat in the curse interface @@ -62,16 +62,11 @@ class Plugin(GlancesPlugin): self.reset() def reset(self): - """ - Reset/init the stats - """ + """Reset/init the stats.""" self.stats = {} def update(self): - """ - Update MEM (RAM) stats using the input method - """ - + """Update RAM memory stats using the input method.""" # Reset stats self.reset() @@ -133,9 +128,7 @@ class Plugin(GlancesPlugin): return self.stats def msg_curse(self, args=None): - """ - Return the dict to display in the curse interface - """ + """Return the dict to display in the curse interface.""" # Init the return message ret = [] diff --git a/glances/plugins/glances_memswap.py b/glances/plugins/glances_memswap.py index 57307ec2..1d0091b3 100644 --- a/glances/plugins/glances_memswap.py +++ b/glances/plugins/glances_memswap.py @@ -16,14 +16,13 @@ # # You should have received a copy of the GNU Lesser General Public License # along with this program. If not, see . -""" -Glances swap memory plugin -""" -import psutil +"""Swap memory plugin.""" from glances.plugins.glances_plugin import GlancesPlugin +import psutil + # SNMP OID # Total Swap Size: .1.3.6.1.4.1.2021.4.3.0 # Available Swap Space: .1.3.6.1.4.1.2021.4.4.0 @@ -32,13 +31,14 @@ snmp_oid = {'total': '1.3.6.1.4.1.2021.4.3.0', class Plugin(GlancesPlugin): - """ - Glances's swap memory Plugin + + """Glances' swap memory plugin. stats is a dict """ def __init__(self, args=None): + """Init the plugin.""" GlancesPlugin.__init__(self, args=args) # We want to display the stat in the curse interface @@ -54,16 +54,11 @@ class Plugin(GlancesPlugin): self.reset() def reset(self): - """ - Reset/init the stats - """ + """Reset/init the stats.""" self.stats = {} def update(self): - """ - Update MEM (SWAP) stats using the input method - """ - + """Update swap memory stats using the input method.""" # Reset stats self.reset() @@ -104,9 +99,7 @@ class Plugin(GlancesPlugin): return self.stats def msg_curse(self, args=None): - """ - Return the dict to display in the curse interface - """ + """Return the dict to display in the curse interface.""" # Init the return message ret = [] diff --git a/glances/plugins/glances_monitor.py b/glances/plugins/glances_monitor.py index 3cefe211..e8fc2616 100644 --- a/glances/plugins/glances_monitor.py +++ b/glances/plugins/glances_monitor.py @@ -17,17 +17,19 @@ # You should have received a copy of the GNU Lesser General Public License # along with this program. If not, see . +"""Monitor plugin.""" + # Import Glances lib -from glances.core.glances_monitor_list import monitorList as glancesMonitorList +from glances.core.glances_monitor_list import MonitorList as glancesMonitorList from glances.plugins.glances_plugin import GlancesPlugin class Plugin(GlancesPlugin): - """ - Glances's monitor Plugin - """ + + """Glances' monitor plugin.""" def __init__(self, args=None): + """Init the plugin.""" GlancesPlugin.__init__(self, args=args) # We want to display the stat in the curse interface @@ -44,17 +46,12 @@ class Plugin(GlancesPlugin): self.stats = [] def load_limits(self, config): - """ - Load the monitored list from the conf file - """ + """Load the monitored list from the conf file.""" # print "DEBUG: Monitor plugin load config file %s" % config self.glances_monitors = glancesMonitorList(config) def update(self): - """ - Update the monitored list - """ - + """Update the monitored list.""" if self.get_input() == 'local': # Monitor list only available in a full Glances environment # Check if the glances_monitor instance is init @@ -72,7 +69,7 @@ class Plugin(GlancesPlugin): return self.stats def get_alert(self, nbprocess=0, countmin=None, countmax=None, header="", log=False): - # Return the alert status relative to the process number + """Return the alert status relative to the process number.""" if nbprocess is None: return 'OK' if countmin is None: @@ -91,9 +88,7 @@ class Plugin(GlancesPlugin): return 'CRITICAL' def msg_curse(self, args=None): - """ - Return the dict to display in the curse interface - """ + """Return the dict to display in the curse interface.""" # Init the return message ret = [] diff --git a/glances/plugins/glances_network.py b/glances/plugins/glances_network.py index d9bd26df..356832f1 100644 --- a/glances/plugins/glances_network.py +++ b/glances/plugins/glances_network.py @@ -16,17 +16,14 @@ # # You should have received a copy of the GNU Lesser General Public License # along with this program. If not, see . -""" -Glances Network interface plugin -""" -# Import system libs -import psutil +"""Network plugin.""" -# Import Glances lib from glances.core.glances_timer import getTimeSinceLastUpdate from glances.plugins.glances_plugin import GlancesPlugin +import psutil + # SNMP OID # http://www.net-snmp.org/docs/mibs/interfaces.html # Dict key = interface_name @@ -36,13 +33,14 @@ snmp_oid = {'interface_name': '1.3.6.1.2.1.2.2.1.2', class Plugin(GlancesPlugin): - """ - Glances's network Plugin + + """Glances' network Plugin. stats is a list """ def __init__(self, args=None): + """Init the plugin.""" GlancesPlugin.__init__(self, args=args) # We want to display the stat in the curse interface @@ -58,17 +56,14 @@ class Plugin(GlancesPlugin): self.reset() def reset(self): - """ - Reset/init the stats - """ + """Reset/init the stats.""" self.stats = [] def update(self): - """ - Update network stats using the input method + """Update network stats using the input method. + Stats is a list of dict (one dict per interface) """ - # Reset stats self.reset() @@ -165,11 +160,8 @@ class Plugin(GlancesPlugin): return self.stats def msg_curse(self, args=None): - """ - Return the dict to displayoid in the curse interface - """ - - #!!! TODO: Add alert on network interface bitrate + """Return the dict to display in the curse interface.""" + # !!! TODO: Add alert on network interface bitrate # Init the return message ret = [] diff --git a/glances/plugins/glances_now.py b/glances/plugins/glances_now.py index a8707646..a7713ae5 100644 --- a/glances/plugins/glances_now.py +++ b/glances/plugins/glances_now.py @@ -25,14 +25,14 @@ from glances.plugins.glances_plugin import GlancesPlugin class Plugin(GlancesPlugin): - """ - Glances' Core Plugin - Get current date/time + + """Plugin to get the current date/time. stats is (string) """ def __init__(self, args=None): + """Init the plugin.""" GlancesPlugin.__init__(self, args=args) # We want to display the stat in the curse interface @@ -45,19 +45,14 @@ class Plugin(GlancesPlugin): self.line_curse = -1 def update(self): - """ - Update current date/time - """ + """Update current date/time.""" # Had to convert it to string because datetime is not JSON serializable self.stats = datetime.now().strftime(_("%Y-%m-%d %H:%M:%S")) return self.stats def msg_curse(self, args=None): - """ - Return the string to display in the curse interface - """ - + """Return the string to display in the curse interface.""" # Init the return message ret = [] diff --git a/glances/plugins/glances_percpu.py b/glances/plugins/glances_percpu.py index 0bdf04c6..d6de4fa9 100644 --- a/glances/plugins/glances_percpu.py +++ b/glances/plugins/glances_percpu.py @@ -16,25 +16,25 @@ # # You should have received a copy of the GNU Lesser General Public License # along with this program. If not, see . -""" -CPU stats (per cpu) -""" -# Check for psutil already done in the glances_core script -import psutil +"""Per-CPU plugin.""" # Import Glances libs from glances.plugins.glances_plugin import GlancesPlugin +# Check for psutil already done in the glances_core script +import psutil + class Plugin(GlancesPlugin): - """ - Glances' PerCpu Plugin + + """Glances' per-CPU plugin. stats is a list """ def __init__(self, args=None): + """Init the plugin.""" GlancesPlugin.__init__(self, args=args) # We want to display the stat in the curse interface @@ -52,16 +52,11 @@ class Plugin(GlancesPlugin): self.percputime_new = [] def reset(self): - """ - Reset/init the stats - """ + """Reset/init the stats.""" self.stats = [] def update(self): - """ - Update Per CPU stats using the input method - """ - + """Update per-CPU stats using the input method.""" # Reset stats self.reset() @@ -138,10 +133,7 @@ class Plugin(GlancesPlugin): return self.stats def msg_curse(self, args=None): - """ - Return the dict to display in the curse interface - """ - + """Return the dict to display in the curse interface.""" # Init the return message ret = [] diff --git a/glances/plugins/glances_plugin.py b/glances/plugins/glances_plugin.py index 95408ba9..a1daf1c9 100644 --- a/glances/plugins/glances_plugin.py +++ b/glances/plugins/glances_plugin.py @@ -16,9 +16,11 @@ # # You should have received a copy of the GNU Lesser General Public License # along with this program. If not, see . + """ I am your father... -For all Glances plugins + +...for all Glances plugins. """ # Import system libs @@ -29,11 +31,11 @@ from glances.core.glances_globals import glances_logs class GlancesPlugin(object): - """ - Main class for Glances' plugin - """ + + """Main class for Glances' plugin.""" def __init__(self, args=None): + """Init the plugin of plugins class.""" # Plugin name (= module name without glances_) self.plugin_name = self.__class__.__module__[len('glances_'):] @@ -50,17 +52,17 @@ class GlancesPlugin(object): self.limits = dict() def __repr__(self): - # Return the raw stats + """Return the raw stats.""" return self.stats def __str__(self): - # Return the human-readable stats + """Return the human-readable stats.""" return str(self.stats) def set_input(self, input_method): - """ - Set the input method: - * local: system local grab (PSUtil or direct access) + """Set the input method. + + * local: system local grab (psutil or direct access) * snmp: Client server mode via SNMP * glances: Client server mode via Glances API """ @@ -68,19 +70,19 @@ class GlancesPlugin(object): return self.input_method def get_input(self): - """ - Get the input method - """ + """Get the input method.""" return self.input_method def set_stats(self, input_stats): - # Set the stats to input_stats + """Set the stats to input_stats.""" self.stats = input_stats return self.stats def set_stats_snmp(self, bulk=False, snmp_oid={}): - # Update stats using SNMP - # If bulk=True, use a bulk request instead of a get request + """Update stats using SNMP. + + If bulk=True, use a bulk request instead of a get request. + """ from glances.core.glances_snmp import GlancesSNMPClient # Init the SNMP request @@ -122,17 +124,15 @@ class GlancesPlugin(object): return ret def get_raw(self): - # Return the stats object + """Return the stats object.""" return self.stats def get_stats(self): - # Return the stats object in JSON format for the RPC API + """Return the stats object in JSON format for the XML-RPC API.""" return json.dumps(self.stats) def load_limits(self, config): - """ - Load the limits from the configuration file - """ + """Load the limits from the configuration file.""" if (hasattr(config, 'has_section') and config.has_section(self.plugin_name)): # print "Load limits for %s" % self.plugin_name @@ -145,27 +145,29 @@ class GlancesPlugin(object): self.limits[self.plugin_name + '_' + s] = config.get_raw_option(self.plugin_name, s).split(",") def set_limits(self, input_limits): - # Set the limits to input_limits + """Set the limits to input_limits.""" self.limits = input_limits return self.limits def get_limits(self): - # Return the limits object + """Return the limits object.""" return self.limits def get_alert(self, current=0, min=0, max=100, header="", log=False): - # Return the alert status relative to a current value - # Use this function for minor stat - # If current < CAREFUL of max then alert = OK - # If current > CAREFUL of max then alert = CAREFUL - # If current > WARNING of max then alert = WARNING - # If current > CRITICAL of max then alert = CRITICAL - # - # If defined 'header' is added between the plugin name and the status - # Only usefull for stats with several alert status - # - # If log=True than return the logged status + """Return the alert status relative to a current value. + Use this function for minor stats. + + If current < CAREFUL of max then alert = OK + If current > CAREFUL of max then alert = CAREFUL + If current > WARNING of max then alert = WARNING + If current > CRITICAL of max then alert = CRITICAL + + If defined 'header' is added between the plugin name and the status. + Only useful for stats with several alert status. + + If log=True than return the logged status. + """ # Compute the % try: value = (current * 100) / max @@ -206,6 +208,7 @@ class GlancesPlugin(object): return ret + log_str def get_alert_log(self, current=0, min=0, max=100, header=""): + """Get the alert log.""" return self.get_alert(current, min, max, header, log=True) def __get_limit_critical(self, header=""): @@ -227,9 +230,7 @@ class GlancesPlugin(object): return self.limits[self.plugin_name + '_' + header + '_' + 'careful'] def get_hide(self, header=""): - """ - Return the hide configuration list key for the current plugin - """ + """Return the hide configuration list key for the current plugin.""" if header == "": try: return self.limits[self.plugin_name + '_' + 'hide'] @@ -242,26 +243,23 @@ class GlancesPlugin(object): return [] def is_hide(self, value, header=""): - """ - Return True if the value is in the hide configuration list - """ + """Return True if the value is in the hide configuration list.""" return value in self.get_hide(header=header) def msg_curse(self, args): - """ - Return default string to display in the curse interface - """ + """Return default string to display in the curse interface.""" return [self.curse_add_line(str(self.stats))] def get_stats_display(self, args=None): - # Return a dict with all the information needed to display the stat - # key | description - #---------------------------- - # display | Display the stat (True or False) - # msgdict | Message to display (list of dict [{ 'msg': msg, 'decoration': decoration } ... ]) - # column | column number - # line | Line number + """Return a dict with all the information needed to display the stat. + key | description + ---------------------------- + display | Display the stat (True or False) + msgdict | Message to display (list of dict [{ 'msg': msg, 'decoration': decoration } ... ]) + column | column number + line | Line number + """ display_curse = False column_curse = -1 line_curse = -1 @@ -279,9 +277,9 @@ class GlancesPlugin(object): 'line': line_curse} def curse_add_line(self, msg, decoration="DEFAULT", optional=False, splittable=False): - """ - Return a dict with: { 'msg': msg, 'decoration': decoration, 'optional': False } - with: + """Return a dict with: { 'msg': msg, 'decoration': decoration, 'optional': False }. + + Where: msg: string decoration: DEFAULT: no decoration @@ -302,19 +300,16 @@ class GlancesPlugin(object): optional: True if the stat is optional (display only if space is available) spittable: Line can be splitted to fit on the screen (default is not) """ - return {'msg': msg, 'decoration': decoration, 'optional': optional, 'splittable': splittable} def curse_new_line(self): - """ - Go to a new line - """ + """Go to a new line.""" return self.curse_add_line('\n') def auto_unit(self, number, low_precision=False): - """ - Make a nice human readable string out of number - Number of decimal places increases as quantity approaches 1 + """Make a nice human-readable string out of number. + + Number of decimal places increases as quantity approaches 1. examples: CASE: 613421788 RESULT: 585M low_precision: 585M @@ -325,8 +320,8 @@ class GlancesPlugin(object): CASE: 1073741824 RESULT: 1024M low_precision: 1024M CASE: 1181116006 RESULT: 1.10G low_precision: 1.1G - parameter 'low_precision=True' returns less decimal places. - potentially sacrificing precision for more readability + 'low_precision=True' returns less decimal places potentially + sacrificing precision for more readability. """ symbols = ('K', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y') prefix = { diff --git a/glances/plugins/glances_processcount.py b/glances/plugins/glances_processcount.py index be757d59..0de5a6a9 100644 --- a/glances/plugins/glances_processcount.py +++ b/glances/plugins/glances_processcount.py @@ -17,19 +17,22 @@ # You should have received a copy of the GNU Lesser General Public License # along with this program. If not, see . +"""Process count plugin.""" + # Import Glances libs from glances.core.glances_globals import glances_processes from glances.plugins.glances_plugin import GlancesPlugin class Plugin(GlancesPlugin): - """ - Glances's processes Plugin + + """Glances' processes plugin. stats is a list """ def __init__(self, args=None): + """Init the plugin.""" GlancesPlugin.__init__(self, args=args) # We want to display the stat in the curse interface @@ -44,16 +47,11 @@ class Plugin(GlancesPlugin): # Note: 'glances_processes' is already init in the glances_processes.py script def reset(self): - """ - Reset/init the stats - """ + """Reset/init the stats.""" self.stats = {} def update(self): - """ - Update processes stats using the input method - """ - + """Update processes stats using the input method.""" # Reset stats self.reset() @@ -72,10 +70,7 @@ class Plugin(GlancesPlugin): return self.stats def msg_curse(self, args=None): - """ - Return the dict to display in the curse interface - """ - + """Return the dict to display in the curse interface.""" # Init the return message ret = [] diff --git a/glances/plugins/glances_processlist.py b/glances/plugins/glances_processlist.py index 85e74e09..b76b292e 100644 --- a/glances/plugins/glances_processlist.py +++ b/glances/plugins/glances_processlist.py @@ -17,6 +17,8 @@ # You should have received a copy of the GNU Lesser General Public License # along with this program. If not, see . +"""Process list plugin.""" + # Import sys libs import os from datetime import timedelta @@ -27,13 +29,14 @@ from glances.plugins.glances_plugin import GlancesPlugin class Plugin(GlancesPlugin): - """ - Glances's processes Plugin + + """Glances' processes plugin. stats is a list """ def __init__(self, args=None): + """Init the plugin.""" GlancesPlugin.__init__(self, args=args) # We want to display the stat in the curse interface @@ -48,16 +51,11 @@ class Plugin(GlancesPlugin): # Note: 'glances_processes' is already init in the glances_processes.py script def reset(self): - """ - Reset/init the stats - """ + """Reset/init the stats.""" self.stats = [] def update(self): - """ - Update processes stats using the input method - """ - + """Update processes stats using the input method.""" # Reset stats self.reset() @@ -74,10 +72,7 @@ class Plugin(GlancesPlugin): return self.stats def msg_curse(self, args=None): - """ - Return the dict to display in the curse interface - """ - + """Return the dict to display in the curse interface.""" # Init the return message ret = [] @@ -226,9 +221,7 @@ class Plugin(GlancesPlugin): return ret def sortlist(self, sortedby=None): - """ - Return the self.stats sorted by sortedby - """ + """Return the stats sorted by sortedby variable.""" if sortedby is None: # No need to sort... return self.stats diff --git a/glances/plugins/glances_psutilversion.py b/glances/plugins/glances_psutilversion.py index b6a2d3eb..dc872cd4 100644 --- a/glances/plugins/glances_psutilversion.py +++ b/glances/plugins/glances_psutilversion.py @@ -17,34 +17,30 @@ # You should have received a copy of the GNU Lesser General Public License # along with this program. If not, see . -from psutil import __version__ as __psutil_version__ - from glances.plugins.glances_plugin import GlancesPlugin +from psutil import __version__ as __psutil_version + class Plugin(GlancesPlugin): - """ - Glances' PsUtil version Plugin + + """Get the psutil version for client/server purposes. stats is a tuple """ def __init__(self, args=None): + """Init the plugin.""" GlancesPlugin.__init__(self, args=args) self.reset() def reset(self): - """ - Reset/init the stats - """ + """Reset/init the stats.""" self.stats = None def update(self): - """ - Update core stats - """ - + """Update the stats.""" # Reset stats self.reset() @@ -52,7 +48,7 @@ class Plugin(GlancesPlugin): if self.get_input() == 'local': # PsUtil version only available in local try: - self.stats = tuple([int(num) for num in __psutil_version__.split('.')]) + self.stats = tuple([int(num) for num in __psutil_version.split('.')]) except NameError: pass else: diff --git a/glances/plugins/glances_sensors.py b/glances/plugins/glances_sensors.py index 9b18e8c6..241706e0 100644 --- a/glances/plugins/glances_sensors.py +++ b/glances/plugins/glances_sensors.py @@ -17,6 +17,8 @@ # You should have received a copy of the GNU Lesser General Public License # along with this program. If not, see . +"""Sensors plugin.""" + # Sensors library (optional; Linux-only) # Py3Sensors: https://bitbucket.org/gleb_zhulik/py3sensors try: @@ -32,19 +34,20 @@ from glances.plugins.glances_plugin import GlancesPlugin class Plugin(GlancesPlugin): - """ - Glances' sensors plugin - The stats list includes both sensors and hard disks stats, if any - The sensors are already grouped by chip type and then sorted by name - The hard disks are already sorted by name + """Glances' sensors plugin. + + The stats list includes both sensors and hard disks stats, if any. + The sensors are already grouped by chip type and then sorted by name. + The hard disks are already sorted by name. """ def __init__(self, args=None): + """Init the plugin.""" GlancesPlugin.__init__(self, args=args) # Init the sensor class - self.glancesgrabsensors = glancesGrabSensors() + self.glancesgrabsensors = GlancesGrabSensors() # Instance for the HDDTemp Plugin in order to display the hard disks temperatures self.hddtemp_plugin = HddTempPlugin() @@ -65,16 +68,11 @@ class Plugin(GlancesPlugin): self.reset() def reset(self): - """ - Reset/init the stats - """ + """Reset/init the stats.""" self.stats = [] def update(self): - """ - Update sensors stats using the input method - """ - + """Update sensors stats using the input method.""" # Reset the stats self.reset() @@ -95,8 +93,9 @@ class Plugin(GlancesPlugin): return self.stats def __set_type(self, stats, sensor_type): - """ - 3 types of stats is possible in the Sensors plugins: + """Set the plugin type. + + 3 types of stats is possible in the sensors plugin: - Core temperature - HDD temperature - Battery capacity @@ -106,9 +105,7 @@ class Plugin(GlancesPlugin): return stats def msg_curse(self, args=None): - """ - Return the dict to display in the curse interface - """ + """Return the dict to display in the curse interface.""" # Init the return message ret = [] @@ -143,15 +140,12 @@ class Plugin(GlancesPlugin): return ret -class glancesGrabSensors: - """ - Get sensors stats using the PySensors library - """ +class GlancesGrabSensors(object): + + """Get sensors stats using the py3sensors library.""" def __init__(self): - """ - Init sensors stats - """ + """Init sensors stats.""" try: sensors.init() except Exception: @@ -163,15 +157,11 @@ class glancesGrabSensors: self.reset() def reset(self): - """ - Reset/init the stats - """ + """Reset/init the stats.""" self.sensors_list = [] def __update__(self): - """ - Update the stats - """ + """Update the stats.""" # Reset the list self.reset() @@ -188,9 +178,11 @@ class glancesGrabSensors: return self.sensors_list def get(self): + """Get sensors list.""" self.__update__() return self.sensors_list def quit(self): + """End of connection.""" if self.initok: sensors.cleanup() diff --git a/glances/plugins/glances_system.py b/glances/plugins/glances_system.py index 922b43ae..d51ace3c 100644 --- a/glances/plugins/glances_system.py +++ b/glances/plugins/glances_system.py @@ -16,9 +16,8 @@ # # You should have received a copy of the GNU Lesser General Public License # along with this program. If not, see . -""" -Glances system plugin -""" + +"""System plugin.""" # Import system libs import os @@ -31,14 +30,16 @@ from glances.plugins.glances_plugin import GlancesPlugin snmp_oid = {'hostname': '1.3.6.1.2.1.1.5.0', 'os_name': '1.3.6.1.2.1.1.1.0'} + class Plugin(GlancesPlugin): - """ - Glances' Host/System Plugin + + """Glances' host/system plugin. stats is a dict """ def __init__(self, args=None): + """Init the plugin.""" GlancesPlugin.__init__(self, args=args) # We want to display the stat in the curse interface @@ -54,17 +55,14 @@ class Plugin(GlancesPlugin): self.reset() def reset(self): - """ - Reset/init the stats - """ + """Reset/init the stats.""" self.stats = {} def update(self): - """ - Update the host/system info using the input method + """Update the host/system info using the input method. + Return the stats (dict) """ - # Reset stats self.reset() @@ -97,10 +95,7 @@ class Plugin(GlancesPlugin): return self.stats def msg_curse(self, args=None): - """ - Return the string to display in the curse interface - """ - + """Return the string to display in the curse interface.""" # Init the return message ret = [] diff --git a/glances/plugins/glances_uptime.py b/glances/plugins/glances_uptime.py index e482d230..85a59beb 100644 --- a/glances/plugins/glances_uptime.py +++ b/glances/plugins/glances_uptime.py @@ -17,27 +17,30 @@ # You should have received a copy of the GNU Lesser General Public License # along with this program. If not, see . +"""Uptime plugin.""" + # Import system libs from datetime import datetime, timedelta -# Check for psutil already done in the glances_core script -import psutil - # Import Glances libs from glances.plugins.glances_plugin import GlancesPlugin +# Check for psutil already done in the glances_core script +import psutil + # SNMP OID snmp_oid = {'_uptime': '1.3.6.1.2.1.1.3.0'} + class Plugin(GlancesPlugin): - """ - Glances' Uptime Plugin - Get stats about uptime + + """Glances' uptime plugin. stats is date (string) """ def __init__(self, args=None): + """Init the plugin.""" GlancesPlugin.__init__(self, args=args) # We want to display the stat in the curse interface @@ -52,16 +55,11 @@ class Plugin(GlancesPlugin): self.reset() def reset(self): - """ - Reset/init the stats - """ + """Reset/init the stats.""" self.stats = {} def update(self): - """ - Update uptime stat using the input method - """ - + """Update uptime stat using the input method.""" # Reset stats self.reset() @@ -84,10 +82,7 @@ class Plugin(GlancesPlugin): return self.stats def msg_curse(self, args=None): - """ - Return the string to display in the curse interface - """ - + """Return the string to display in the curse interface.""" # Init the return message ret = [] diff --git a/i18n/de/LC_MESSAGES/glances.mo b/i18n/de/LC_MESSAGES/glances.mo index 53892484..08e342d2 100644 Binary files a/i18n/de/LC_MESSAGES/glances.mo and b/i18n/de/LC_MESSAGES/glances.mo differ diff --git a/i18n/de/LC_MESSAGES/glances.po b/i18n/de/LC_MESSAGES/glances.po index d87437eb..4a28cfb6 100644 --- a/i18n/de/LC_MESSAGES/glances.po +++ b/i18n/de/LC_MESSAGES/glances.po @@ -5,10 +5,17 @@ # msgid "" msgstr "" -"Project-Id-Version: GLANCES 2.0_RC1\n" +<<<<<<< HEAD +"Project-Id-Version: GLANCES 1.7.6\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2014-05-27 13:03+0200\n" -"PO-Revision-Date: 2014-05-27 17:44+0100\n" +"POT-Creation-Date: 2014-03-27 18:39+0100\n" +"PO-Revision-Date: 2014-03-27 19:07+0100\n" +======= +"Project-Id-Version: GLANCES 2.0_RC4\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2014-06-03 16:21+0200\n" +"PO-Revision-Date: 2014-06-03 16:33+0100\n" +>>>>>>> release/v2.0 "Last-Translator: David Tiersch \n" "Language-Team: German\n" "Language: de\n" @@ -16,6 +23,385 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" +<<<<<<< HEAD +"X-Generator: Poedit 1.6.4\n" + +#: glances/glances.py:405 +#, python-format +msgid "Error decoding config file '%s': %s" +msgstr "Fehler beim Dekodieren der Konfig-Datei '%s': %s" + +#: glances/glances.py:1152 +msgid "hddtemp error" +msgstr "hddtemp-Fehler" + +#: glances/glances.py:2099 +msgid "Error: Cannot init the curses library.\n" +msgstr "Fehler: Die curses-Bibliothek kann nicht initialisiert werden.\n" + +#: glances/glances.py:2664 +msgid "{0} ({1} {2} / {3} {4})" +msgstr "{0} ({1} {2} / {3} {4})" + +#: glances/glances.py:2669 +msgid "{0} ({1} {2} {3})" +msgstr "{0} ({1} {2} {3})" + +#: glances/glances.py:2675 +msgid "Uptime: {0}" +msgstr "Betriebszeit: {0}" + +#: glances/glances.py:2738 +msgid "PerCPU" +msgstr "Pro CPU" + +#: glances/glances.py:2744 glances/glances.py:2798 glances/glances.py:3103 +#: glances/glances.py:3267 glances/glances.py:3672 +msgid "Compute data..." +msgstr "Berechne Daten..." + +#: glances/glances.py:2748 glances/glances.py:2808 +msgid "user:" +msgstr "" + +#: glances/glances.py:2750 glances/glances.py:2817 +msgid "system:" +msgstr "" + +#: glances/glances.py:2753 glances/glances.py:2854 +msgid "iowait:" +msgstr "" + +#: glances/glances.py:2756 glances/glances.py:2824 +msgid "idle:" +msgstr "" + +#: glances/glances.py:2792 +msgid "CPU" +msgstr "CPU" + +#: glances/glances.py:2835 +msgid "steal:" +msgstr "" + +#: glances/glances.py:2845 +msgid "nice:" +msgstr "" + +#: glances/glances.py:2864 +msgid "irq:" +msgstr "" + +#: glances/glances.py:2886 glances/glances.py:3890 +msgid "Load" +msgstr "Last" + +#: glances/glances.py:2890 +msgid "-core" +msgstr "" + +#: glances/glances.py:2894 +msgid "1 min:" +msgstr "1 min:" + +#: glances/glances.py:2901 +msgid "5 min:" +msgstr "5 min:" + +#: glances/glances.py:2911 +msgid "15 min:" +msgstr "15 min:" + +#: glances/glances.py:2943 +msgid "Mem" +msgstr "" + +#: glances/glances.py:2953 glances/glances.py:3039 +msgid "total:" +msgstr "" + +#: glances/glances.py:2962 glances/glances.py:3049 +msgid "used:" +msgstr "belegt:" + +#: glances/glances.py:2970 glances/glances.py:3058 +msgid "free:" +msgstr "frei:" + +#: glances/glances.py:2983 +msgid "active:" +msgstr "aktiv:" + +#: glances/glances.py:2991 +msgid "inactive:" +msgstr "inaktiv:" + +#: glances/glances.py:3001 +msgid "buffers:" +msgstr "Buffer:" + +#: glances/glances.py:3009 +msgid "cached:" +msgstr "gecached:" + +#: glances/glances.py:3027 +msgid "Swap" +msgstr "" + +#: glances/glances.py:3075 +msgid "Network" +msgstr "Netzwerk" + +#: glances/glances.py:3098 glances/glances.py:3262 +msgid "Cannot grab data..." +msgstr "Kann Daten nicht lesen..." + +#: glances/glances.py:3189 +msgid "Sensors" +msgstr "Sensoren" + +#: glances/glances.py:3192 glances/glances.py:3225 +msgid "°C" +msgstr "°C" + +#: glances/glances.py:3222 +msgid "HDD Temp" +msgstr "" + +#: glances/glances.py:3251 +msgid "Disk I/O" +msgstr "" + +#: glances/glances.py:3255 +msgid "In/s" +msgstr "" + +#: glances/glances.py:3257 +msgid "Out/s" +msgstr "" + +#: glances/glances.py:3303 +msgid "Mount" +msgstr "" + +#: glances/glances.py:3307 +msgid "Used" +msgstr "Belegt" + +#: glances/glances.py:3309 +msgid "Total" +msgstr "" + +#: glances/glances.py:3351 +msgid "WARNING|CRITICAL logs" +msgstr "WARNUNG|KRITISCH Logs" + +#: glances/glances.py:3353 +msgid " (lasts " +msgstr " (letzte" + +#: glances/glances.py:3354 +msgid " entries)" +msgstr " Einträge)" + +#: glances/glances.py:3356 +msgid " (one entry)" +msgstr " (ein Eintrag)" + +#: glances/glances.py:3455 +msgid "Processes (disabled)" +msgstr "Prozesse (deaktiviert)" + +#: glances/glances.py:3470 +msgid "Tasks" +msgstr "" + +#: glances/glances.py:3478 +msgid "thr" +msgstr "" + +#: glances/glances.py:3480 +msgid "run" +msgstr "" + +#: glances/glances.py:3482 +msgid "slp" +msgstr "" + +#: glances/glances.py:3484 +msgid "oth" +msgstr "" + +#: glances/glances.py:3490 +msgid "sorted automatically" +msgstr "automatisch sortiert" + +#: glances/glances.py:3492 +msgid "sorted by " +msgstr "sortiert nach " + +#: glances/glances.py:3516 +msgid "RUNNING" +msgstr "LAUFEND" + +#: glances/glances.py:3516 +msgid "NOT RUNNING" +msgstr "NICHT LAUFEND" + +#: glances/glances.py:3530 +msgid "Error: " +msgstr "Fehler: " + +#: glances/glances.py:3532 +msgid "Cannot execute command" +msgstr "Kann Kommando nicht ausführen" + +#: glances/glances.py:3592 +msgid "VIRT" +msgstr "" + +#: glances/glances.py:3596 +msgid "RES" +msgstr "" + +#: glances/glances.py:3600 +msgid "CPU%" +msgstr "CPU%" + +#: glances/glances.py:3605 +msgid "MEM%" +msgstr "" + +#: glances/glances.py:3613 +msgid "PID" +msgstr "" + +#: glances/glances.py:3619 +msgid "USER" +msgstr "" + +#: glances/glances.py:3625 +msgid "NI" +msgstr "" + +#: glances/glances.py:3631 +msgid "S" +msgstr "" + +#: glances/glances.py:3637 +msgid "TIME+" +msgstr "ZEIT+" + +#: glances/glances.py:3643 +msgid "IOR/s" +msgstr "" + +#: glances/glances.py:3648 +msgid "IOW/s" +msgstr "" + +#: glances/glances.py:3666 +msgid "NAME" +msgstr "NAME" + +#: glances/glances.py:3828 +msgid "Connected to " +msgstr "Verbunden zu " + +#: glances/glances.py:3831 +msgid "Disconnected from " +msgstr "Verbindung getrennt zu " + +#: glances/glances.py:3833 +msgid "Press 'h' for help" +msgstr "Drück 'h' für Hilfe" + +#: glances/glances.py:3865 +msgid "Glances {0} with PsUtil {1}" +msgstr "Glances {0} mit PsUtil {1}" + +#: glances/glances.py:3871 +msgid "Glances {0}" +msgstr "Glances {0}" + +#: glances/glances.py:3878 +msgid "CAREFUL" +msgstr "VORSICHT" + +#: glances/glances.py:3881 +msgid "WARNING" +msgstr "WARNUNG" + +#: glances/glances.py:3884 +msgid "CRITICAL" +msgstr "KRITISCH" + +#: glances/glances.py:3888 +msgid "CPU user %" +msgstr "" + +#: glances/glances.py:3888 +msgid "CPU system %" +msgstr "" + +#: glances/glances.py:3889 +msgid "CPU iowait %" +msgstr "" + +#: glances/glances.py:3889 +msgid "CPU steal %" +msgstr "" + +#: glances/glances.py:3890 +msgid "RAM %" +msgstr "" + +#: glances/glances.py:3927 +msgid "Swap %" +msgstr "" + +#: glances/glances.py:3927 +msgid "Temp °C" +msgstr "Temp °C" + +#: glances/glances.py:3928 +msgid "HDD Temp °C" +msgstr "" + +#: glances/glances.py:3928 +msgid "Filesystem %" +msgstr "Dateisystem %" + +#: glances/glances.py:3929 +msgid "CPU process %" +msgstr "CPU Prozess %" + +#: glances/glances.py:3929 +msgid "MEM process %" +msgstr "MEM Prozess %" + +#: glances/glances.py:3965 +msgid "a" +msgstr "a" + +#: glances/glances.py:3965 +msgid "Sort processes automatically" +msgstr "Prozesse automatisch sortieren" + +#: glances/glances.py:3966 +msgid "c" +msgstr "c" + +#: glances/glances.py:3966 +msgid "Sort processes by CPU%" +msgstr "Prozesse nach CPU% sortieren" + +#: glances/glances.py:3967 +msgid "m" +msgstr "m" + +#: glances/glances.py:3967 +======= "X-Generator: Poedit 1.5.4\n" "X-Poedit-Basepath: ~/dev/glances\n" @@ -28,6 +414,11 @@ msgstr "Fehler: Die Server-Version ist mit dem Client nicht kompatibel" msgid "Glances server is running on {0}:{1}" msgstr "Glances-Server läuft auf {0}:{1}" +#: glances/core/glances_stats.py:264 +#, python-brace-format +msgid "Error: Update {0} failed: {1}" +msgstr "Fehler: Aktualisierung {0} ist fehlgeschlagen: {1}" + #: glances/core/glances_client.py:62 #, python-brace-format msgid "Error: Couldn't create socket {0}: {1}" @@ -54,71 +445,13 @@ msgstr "Fehler: Verbindung zum SNMP-Server fehlgeschlagen" #: glances/core/glances_client.py:147 #, python-brace-format -msgid "Error: Unknown server mode ({0})" -msgstr "Fehler: Unbekannter Servers-Modus ({0})" +msgid "Error: Unknown server mode: {0}" +msgstr "Fehler: Unbekannter Servers-Modus: {0}" #: glances/core/glances_config.py:71 #, python-brace-format -msgid "Error decoding configuration file '{0}': {1}" -msgstr "Fehler beim Lesen der Konfigurationsdatei '{0}': {1}" - -#: glances/core/glances_monitor_list.py:74 -#, python-format -msgid "Error reading monitored list: %s" -msgstr "Beim Lesen der Überwachungs-Liste trat ein Fehler auf: %s" - -#: glances/core/glances_monitor_list.py:143 -msgid "Error: " -msgstr "Fehler: " - -#: glances/core/glances_monitor_list.py:145 -msgid "Cannot execute command" -msgstr "Kann Befehl nicht ausführen" - -#: glances/core/glances_password.py:111 -#, python-format -msgid "[Info] Read password from file %s\n" -msgstr "[Info] Passwort gelesen aus Datei %s\n" - -#: glances/core/glances_password.py:120 -msgid "Password: " -msgstr "Passwort:" - -#: glances/core/glances_password.py:124 -msgid "Password (confirm): " -msgstr "Passwort (wiederholen):" - -#: glances/core/glances_password.py:127 -msgid "[Error] Sorry, but passwords did not match...\n" -msgstr "[Fehler] Passwörter stimmen nicht überein...\n" - -#: glances/core/glances_password.py:138 -msgid "Do you want to save the password? [Yes/No]: " -msgstr "Willst du das Passwort speichern? [Ja/Nein]" - -#: glances/core/glances_password.py:139 -msgid "Y" -msgstr "J" - -#: glances/core/glances_password.py:154 -#, python-brace-format -msgid "[Warning] Cannot create Glances directory: {0}" -msgstr "[Warnung] Kann Glances-Ordner nicht erzeugen: {0}" - -#: glances/core/glances_server.py:115 -#, python-format -msgid "Couldn't open socket: %s" -msgstr "Kann Socket nicht öffnen: %s" - -#: glances/core/glances_server.py:205 -#, python-format -msgid "Error: Cannot start Glances server (%s)" -msgstr "Fehler: Kann Glances-Server nicht starten (%s)" - -#: glances/core/glances_stats.py:264 -#, python-brace-format -msgid "Error: Update {0} failed: {1}" -msgstr "Fehler: Aktualisierung {0} ist fehlgeschlagen: {1}" +msgid "Error: Cannot decode configuration file '{0}': {1}" +msgstr "Fehler: Kann Konfigurationsdatei '{0}' nicht lesen: {1}" #: glances/core/glances_main.py:65 msgid "display network rate in byte per second" @@ -169,9 +502,9 @@ msgid "export stats to a CSV file" msgstr "Exportiere Daten zu CSV-Datei" #: glances/core/glances_main.py:92 -#, python-format -msgid "define the client/server TCP port [default: %d]" -msgstr "Client-/Server-TCP-Port festlegen [default: %d]" +#, python-brace-format +msgid "define the client/server TCP port [default: {0}]" +msgstr "Client-/Server-TCP-Port festlegen [default: {0}]" #: glances/core/glances_main.py:94 msgid "define password from the command line" @@ -206,9 +539,9 @@ msgid "SNMP authentication key (only for SNMPv3)" msgstr "SNMP-Authentifizierungs-Schlüssel (nur für SNMPv3)" #: glances/core/glances_main.py:110 -#, python-format -msgid "set refresh time in seconds [default: %s sec]" -msgstr "Aktualisierungszeit in Sekunden [default: %s Sekunden]" +#, python-brace-format +msgid "set refresh time in seconds [default: {0} sec]" +msgstr "Aktualisierungszeit in Sekunden [default: {0} Sek]" #: glances/core/glances_main.py:112 msgid "run Glances in web server mode" @@ -226,19 +559,77 @@ msgstr "Passwort für Glances-Server festlegen" msgid "Enter the Glances server password" msgstr "Passwort für Glances-Server eingeben" +#: glances/core/glances_monitor_list.py:74 +#, python-brace-format +msgid "Error: Cannot read monitored list: {0}" +msgstr "Fehler: Kann Überwachungs-Liste nicht lesen: {0}" + +#: glances/core/glances_monitor_list.py:143 +msgid "Error: " +msgstr "Fehler: " + +#: glances/core/glances_monitor_list.py:145 +msgid "Cannot execute command" +msgstr "Kann Befehl nicht ausführen" + +#: glances/core/glances_password.py:111 +#, python-brace-format +msgid "Info: Read password from file: {0}" +msgstr "Info: Passwort gelesen aus Datei {0}" + +#: glances/core/glances_password.py:120 +msgid "Password: " +msgstr "Passwort:" + +#: glances/core/glances_password.py:124 +msgid "Password (confirm): " +msgstr "Passwort (wiederholen):" + +#: glances/core/glances_password.py:127 +msgid "Error: Sorry, but passwords did not match..." +msgstr "Fehler: Passwörter stimmen nicht überein..." + +#: glances/core/glances_password.py:138 +msgid "Do you want to save the password? [Yes/No]: " +msgstr "Willst du das Passwort speichern? [Ja/Nein]" + +#: glances/core/glances_password.py:139 +msgid "Y" +msgstr "J" + +#: glances/core/glances_password.py:154 +#, python-brace-format +msgid "Warning: Cannot create Glances directory: {0}" +msgstr "Warnung: Kann Glances-Ordner nicht erzeugen: {0}" + +#: glances/core/glances_server.py:115 +#, python-brace-format +msgid "Error: Couldn't open socket: {0}" +msgstr "Fehler: Kann Socket nicht öffnen: {0}" + +#: glances/core/glances_server.py:205 +#, python-brace-format +msgid "Error: Cannot start Glances server: {0}" +msgstr "Fehler: Kann Glances-Server nicht starten: {0}" + +#: glances/outputs/glances_curses.py:61 +msgid "Error: Cannot init the curses library.\n" +msgstr "Fehler: Kann curses-Bibliothek nicht initialisieren.\n" + #: glances/outputs/glances_csv.py:48 #, python-brace-format -msgid "Cannot create the CSV file: {0}" -msgstr "Kann CSV-Datei nicht erzeugen: {0}" +msgid "Error: Cannot create the CSV file: {0}" +msgstr "Fehler: Kann CSV-Datei nicht erzeugen: {0}" #: glances/outputs/glances_csv.py:51 #, python-brace-format msgid "Stats dumped to CSV file: {0}" msgstr "Daten nach CSV-Datei gespeichert: {0}" -#: glances/outputs/glances_curses.py:61 -msgid "Error: Cannot init the curses library.\n" -msgstr "Fehler: Kann curses-Bibliothek nicht initialisieren.\n" +#: glances/plugins/glances_uptime.py:95 +#, python-brace-format +msgid "Uptime: {0}" +msgstr "Betriebszeit: {0}" #: glances/plugins/glances_alert.py:78 msgid "No warning or critical alert detected" @@ -249,21 +640,31 @@ msgid "Warning or critical alerts" msgstr "(Kritische) Warnungen" #: glances/plugins/glances_alert.py:86 -#, python-format -msgid "(lasts %s entries)" -msgstr "(letzte %s Einträge)" +#, python-brace-format +msgid " (lasts {0} entries)" +msgstr " (letzte {0} Einträge)" #: glances/plugins/glances_alert.py:88 -msgid "(one entry)" -msgstr "(ein Eintrag)" +msgid " (one entry)" +msgstr " (ein Eintrag)" #: glances/plugins/glances_alert.py:102 msgid " (ongoing)" msgstr "(laufend)" #: glances/plugins/glances_alert.py:108 -msgid "on" -msgstr "auf" +#, python-brace-format +msgid "{0} on {1}" +msgstr "{0} auf {1}" + +#: glances/plugins/glances_alert.py:117 +#, python-brace-format +msgid " (Min:{0:.1f} Mean:{1:.1f} Max:{2:.1f})" +msgstr " (Min:{0:.1f} Mittel:{1:.1f} Max:{2:.1f})" + +#: glances/plugins/glances_batpercent.py:107 +msgid "Battery (%)" +msgstr "Batterie (%)" #: glances/plugins/glances_cpu.py:123 msgid "CPU" @@ -285,11 +686,11 @@ msgstr "IRQ:" msgid "system:" msgstr "System:" -#: glances/plugins/glances_cpu.py:158 glances/plugins/glances_percpu.py:188 +#: glances/plugins/glances_cpu.py:158 msgid "iowait:" msgstr "IOWait:" -#: glances/plugins/glances_cpu.py:166 +#: glances/plugins/glances_cpu.py:166 glances/plugins/glances_percpu.py:188 msgid "idle:" msgstr "Inaktiv:" @@ -322,8 +723,9 @@ msgid "Total" msgstr "Gesamt" #: glances/plugins/glances_help.py:68 -msgid "with psutil" -msgstr "mit psutil" +#, python-brace-format +msgid " with psutil {0}" +msgstr " mit psutil {0}" #: glances/plugins/glances_help.py:77 msgid "a" @@ -362,9 +764,415 @@ msgid "m" msgstr "m" #: glances/plugins/glances_help.py:87 +>>>>>>> release/v2.0 msgid "Sort processes by MEM%" msgstr "Prozesse nach RAM% sortieren" +<<<<<<< HEAD +#: glances/glances.py:3968 +msgid "p" +msgstr "p" + +#: glances/glances.py:3968 +msgid "Sort processes by name" +msgstr "Prozesse nach Name sortieren" + +#: glances/glances.py:3969 +msgid "i" +msgstr "i" + +#: glances/glances.py:3969 +msgid "Sort processes by I/O rate" +msgstr "Prozesse nach I/O-Rate sortieren" + +#: glances/glances.py:3970 +msgid "d" +msgstr "d" + +#: glances/glances.py:3970 +msgid "Show/hide disk I/O stats" +msgstr "Zeige/Verstecke Disk I/O-Statistik" + +#: glances/glances.py:3971 +msgid "f" +msgstr "f" + +#: glances/glances.py:3971 +msgid "Show/hide file system stats" +msgstr "Zeige/Verstecke Dateisystem-Statistik" + +#: glances/glances.py:3972 +msgid "n" +msgstr "n" + +#: glances/glances.py:3972 +msgid "Show/hide network stats" +msgstr "Zeige/Verstecke Netzwerk-Statistik" + +#: glances/glances.py:3973 +msgid "s" +msgstr "s" + +#: glances/glances.py:3973 +msgid "Show/hide sensors stats" +msgstr "Zeige/Verstecke Sensor-Statisik" + +#: glances/glances.py:3974 +msgid "y" +msgstr "y" + +#: glances/glances.py:3974 +msgid "Show/hide hddtemp stats" +msgstr "Zeige/Verstecke hddtemp-Statistik" + +#: glances/glances.py:3986 +msgid "l" +msgstr "l" + +#: glances/glances.py:3986 +msgid "Show/hide logs" +msgstr "Zeige/Verstecke Logs" + +#: glances/glances.py:3987 +msgid "b" +msgstr "b" + +#: glances/glances.py:3987 +msgid "Bytes or bits for network I/O" +msgstr "Bytes oder Bits für Netzwerk I/O" + +#: glances/glances.py:3988 +msgid "w" +msgstr "w" + +#: glances/glances.py:3988 +msgid "Delete warning logs" +msgstr "Lösche warning-Logs" + +#: glances/glances.py:3989 +msgid "x" +msgstr "x" + +#: glances/glances.py:3989 +msgid "Delete warning and critical logs" +msgstr "Lösche warning- und critical-Logs" + +#: glances/glances.py:3990 +msgid "1" +msgstr "1" + +#: glances/glances.py:3990 +msgid "Global CPU or per-CPU stats" +msgstr "Globale oder Pro-CPU-Statistik" + +#: glances/glances.py:3991 +msgid "h" +msgstr "h" + +#: glances/glances.py:3991 +msgid "Show/hide this help screen" +msgstr "Zeige/Verstecke diesen Hilfe-Bildschirm" + +#: glances/glances.py:3992 +msgid "t" +msgstr "t" + +#: glances/glances.py:3992 +msgid "View network I/O as combination" +msgstr "Zeige Netzwerk I/O kombiniert" + +#: glances/glances.py:3993 +msgid "u" +msgstr "u" + +#: glances/glances.py:3993 +msgid "View cumulative network I/O" +msgstr "Zeige kumulative Netzwerk I/O" + +#: glances/glances.py:3994 +msgid "z" +msgstr "z" + +#: glances/glances.py:3994 +msgid "Show/hide processes list" +msgstr "Zeige/Verstecke Prozess-Liste" + +#: glances/glances.py:3995 +msgid "q" +msgstr "q" + +#: glances/glances.py:3995 +msgid "Quit (Esc and Ctrl-C also work)" +msgstr "Beenden (Esc und Strg-C funktionieren auch)" + +#: glances/glances.py:4028 glances/glances.py:4401 glances/glances.py:4406 +msgid "%Y-%m-%d %H:%M:%S" +msgstr "%d.%m.%Y %H:%M:%S" + +#: glances/glances.py:4285 +#, python-format +msgid "Couldn't open socket: %s" +msgstr "Kann Socket nicht öffnen: %s" + +#: glances/glances.py:4471 +msgid "Error: creating client socket" +msgstr "Fehler: Client-Socket konnte nicht erstellt werden" + +#: glances/glances.py:4479 +#, python-format +msgid "Couldn't create socket: %s" +msgstr "Konnte Socket nicht erzeugen: %s" + +#: glances/glances.py:4483 +msgid "Error: Connection to server failed. Bad password." +msgstr "Fehler: Verbindung zum Server gescheitert. Ungültiges Passwort." + +#: glances/glances.py:4486 +msgid "Error: Connection to server failed. Unknown error." +msgstr "Fehler: Verbindung zum Server gescheitert. Unbekannter Fehler." + +#: glances/glances.py:4519 +msgid "Glances version " +msgstr "Glances Version " + +#: glances/glances.py:4519 +msgid " with PsUtil " +msgstr " mit PsUtil " + +#: glances/glances.py:4524 +msgid "Usage: glances [options]" +msgstr "Benutzung: glances [optionen]" + +#: glances/glances.py:4525 +msgid "" +"\n" +"Options:" +msgstr "" +"\n" +"Optionen:" + +#: glances/glances.py:4526 +msgid "\t-b\t\tDisplay network rate in Byte per second" +msgstr "\t-b\t\tZeige Netzwerk-Rate in Byte pro Sekunde" + +#: glances/glances.py:4527 +msgid "\t-B @IP|HOST\tBind server to the given IPv4/IPv6 address or hostname" +msgstr "" +"\t-B @IP|HOST\tBinde Server an die gegebene IPv4/IPv6 Adresse oder Hostnamen" + +#: glances/glances.py:4528 +msgid "" +"\t-c @IP|HOST\tConnect to a Glances server by IPv4/IPv6 address or hostname" +msgstr "" +"\t-c @IP|HOST\tVerbinde zu einem Glances Server mit by IPv4/IPv6 Adresse " +"oder Hostnamen" + +#: glances/glances.py:4529 +msgid "\t-C FILE\t\tPath to the configuration file" +msgstr "\t-C FILE\t\tPfad zur Konfigurations-Datei" + +#: glances/glances.py:4530 +msgid "\t-d\t\tDisable disk I/O module" +msgstr "\t-d\t\tDeaktiviere Disk I/O-Modul" + +#: glances/glances.py:4531 +msgid "\t-e\t\tEnable sensors module" +msgstr "\t-e\t\tAktiviere Sensor-Modul" + +#: glances/glances.py:4532 +msgid "\t-f FILE\t\tSet the HTML output folder or CSV file" +msgstr "\t-f FILE\t\tSetze den HTML-Ausgabe-Ordner oder die CSV-Datei" + +#: glances/glances.py:4533 +msgid "\t-h\t\tDisplay the help and exit" +msgstr "\t-h\t\tZeige die Hilfe und beende" + +#: glances/glances.py:4534 +msgid "\t-m\t\tDisable mount module" +msgstr "\t-m\t\tDeaktivere Mount-Modul" + +#: glances/glances.py:4535 +msgid "\t-n\t\tDisable network module" +msgstr "\t-n\t\tDeaktiviere Netzwerk-Modul" + +#: glances/glances.py:4536 +msgid "\t-o OUTPUT\tDefine additional output (available: HTML or CSV)" +msgstr "\t-o OUTPUT\tBestimme zusätzliche Ausgabe (verfügbar: HTML oder CSV)" + +#: glances/glances.py:4537 +#, python-format +msgid "\t-p PORT\t\tDefine the client/server TCP port (default: %d)" +msgstr "\t-p PORT\t\tDefiniere den TCP-Port des Clients/Servers (Standard: %d)" + +#: glances/glances.py:4539 +msgid "\t-P PASSWORD\tDefine a client/server password" +msgstr "\t-P PASSWORD\tSetze ein Client-/Server-Passwort" + +#: glances/glances.py:4540 +msgid "\t--password\tDefine a client/server password from the prompt" +msgstr "\t--password\tSetze ein Client-/Server-Passwort auf der Kommandozeile" + +#: glances/glances.py:4541 +msgid "\t-r\t\tDisable process list" +msgstr "\t-r\t\tDeaktiviere Prozess-Liste" + +#: glances/glances.py:4542 +msgid "\t-s\t\tRun Glances in server mode" +msgstr "\t-s\t\tStarte Glances im Server-Modus" + +#: glances/glances.py:4543 +#, python-format +msgid "\t-t SECONDS\tSet refresh time in seconds (default: %d sec)" +msgstr "" +"\t-t SECONDS\tSetze Aktualisierungs-Zeit in Sekunden (Standard: %d sek)" + +#: glances/glances.py:4545 +msgid "\t-v\t\tDisplay the version and exit" +msgstr "\t-v\t\tZeige die Version und beende" + +#: glances/glances.py:4546 +msgid "\t-y\t\tEnable hddtemp module" +msgstr "\t-y\t\tAktiviere hddtemp-Modul" + +#: glances/glances.py:4547 +msgid "\t-z\t\tDo not use the bold color attribute" +msgstr "\t-z\t\tSetze Farben nicht in fett" + +#: glances/glances.py:4548 +msgid "\t-1\t\tStart Glances in per CPU mode" +msgstr "\t-1\t\tStarte Glances im Pro-CPU-Modus" + +#: glances/glances.py:4583 +msgid "Password: " +msgstr "Passwort: " + +#: glances/glances.py:4585 +msgid "Password (confirm): " +msgstr "Passwort (bestätigen): " + +#: glances/glances.py:4592 +msgid "[Warning] Passwords did not match, please try again...\n" +msgstr "" +"[Warnung] Passwörter stimmen nicht überein, bitte erneut versuchen...\n" + +#: glances/glances.py:4664 +msgid "Try 'glances -h' for more information." +msgstr "Versuch 'glances -h' für mehr Informationen." + +#: glances/glances.py:4690 +#, python-format +msgid "Error: Unknown output %s" +msgstr "Fehler: Unbekannte Ausgabe %s" + +#: glances/glances.py:4701 +msgid "Error: Refresh time should be a positive integer" +msgstr "Fehler: Aktualisierungszeit muss eine positive ganze Zahl sein" + +#: glances/glances.py:4727 +msgid "Error: Cannot use both -P and --password flag" +msgstr "Fehler: Kann nicht gleichzeitig -P und --password benutzen" + +#: glances/glances.py:4732 +msgid "Error: Cannot use both -s and -c flag" +msgstr "Fehler: Kann nicht gleichzeitig -s und -c benutzen" + +#: glances/glances.py:4735 +msgid "Error: Cannot use both -s and -o flag" +msgstr "Fehler: Kann nicht gleichzeitig -s und -o benutzen" + +#: glances/glances.py:4738 +msgid "Define the password for the Glances server" +msgstr "Setze das Passwort für den Glances Server" + +#: glances/glances.py:4742 +msgid "Error: Cannot use both -c and -o flag" +msgstr "Fehler: Kann nicht gleichzeitig -c und -o benutzen" + +#: glances/glances.py:4745 +msgid "Error: Cannot use both -c and -C flag" +msgstr "Fehler: Kann nicht gleichzeitig -c und -C benutzen" + +#: glances/glances.py:4746 +msgid "Limits are set based on the server ones" +msgstr "Die Grenzen basieren auf denen des Servers" + +#: glances/glances.py:4749 +msgid "Enter the Glances server password" +msgstr "Gib das Glances Server-Passwort ein" + +#: glances/glances.py:4753 +msgid "Error: Need Jinja2 library to export into HTML" +msgstr "" +"Fehler: Benötige die Bibliothek Jinja2 um nach HTML exportieren zu können" + +#: glances/glances.py:4758 +msgid "" +"Error: HTML export (-o html) need output folder definition (-f )" +msgstr "Fehler: HTML-Export (-o html) benötigt Ausgabe-Ordner (-f )" + +#: glances/glances.py:4764 +msgid "Error: Need CSV library to export into CSV" +msgstr "Fehler: Benötige CSV-Bibliothek um nach CSV zu exportieren" + +#: glances/glances.py:4769 +msgid "Error: CSV export (-o csv) need output file definition (-f )" +msgstr "Fehler: CSV-Export (-o csv) benötigt Ausgabe-Datei (-f )" + +#: glances/glances.py:4799 glances/glances.py:4821 +#, python-format +msgid "Error: Invalid port number: %s" +msgstr "Fehler: Ungültige Port-Nummer: %s" + +#: glances/glances.py:4801 +msgid "Glances server is running on" +msgstr "Glances-Server läuft auf" + +#: glances/glances.py:4826 +msgid "Error: The server version is not compatible" +msgstr "Fehler: Die Server-Version ist nicht kompatibel" + +#~ msgid "{0} {1} with {2} {3} on {4}" +#~ msgstr "{0} {1} mit {2} {3} auf {4}" + +#~ msgid "{0} {1} {2} on {3}" +#~ msgstr "{0} {1} {2} auf {3}" + +#~ msgid "Processes" +#~ msgstr "Prozesse" + +#~ msgid "running" +#~ msgstr "laufend" + +#~ msgid "sleeping" +#~ msgstr "schlafend" + +#~ msgid "other" +#~ msgstr "andere" + +#~ msgid "Error: -P flag need an argument (password)" +#~ msgstr "Fehler: -P benötigt ein Argument (password)" + +#~ msgid "Error: -B flag need an argument (bind IP address)" +#~ msgstr "Fehler: -B benötigt ein Argument (Bind-IP-Adresse)" + +#~ msgid "Error: -c flag need an argument (server IP address/name)" +#~ msgstr "Fehler: -c benötigt ein Argument (Server-IP-Adresse/Name)" + +#~ msgid "Error: PySensors library not found" +#~ msgstr "Fehler: Bibliothek PySensors kann nicht gefunden werden" + +#~ msgid "Error: Sensors module is only available on Linux" +#~ msgstr "Fehler: Das Sensor-Modul ist nur unter Linux verfügbar" + +#~ msgid " Limits are set based on the server ones" +#~ msgstr " Grenzen werden auf Grundlage des Server gesetzt" + +#~ msgid "Try to install the python-jinja2 package" +#~ msgstr "Versuche das Paket python-jinja2 zu installieren" + +#~ msgid "Can not grab data..." +#~ msgstr "Kann nicht auf Daten zugreifen" +======= #: glances/plugins/glances_help.py:89 msgid "w" msgstr "w" @@ -466,8 +1274,8 @@ msgid "z" msgstr "z" #: glances/plugins/glances_help.py:119 -msgid "Enable/Disable processes stats" -msgstr "Prozess-Daten zeigen/verstecken" +msgid "Enable/disable processes stats" +msgstr "Prozess-Daten aktivieren/deaktivieren" #: glances/plugins/glances_help.py:122 msgid "q" @@ -483,8 +1291,8 @@ msgstr "LAST" #: glances/plugins/glances_load.py:127 #, python-brace-format -msgid "{0:>5}-core" -msgstr "{0:>5}-Kern" +msgid "{0}-core" +msgstr "{0}-Kern" #: glances/plugins/glances_load.py:132 msgid "1 min:" @@ -503,49 +1311,37 @@ msgid "MEM" msgstr "RAM" #: glances/plugins/glances_mem.py:155 -msgid "active" -msgstr "aktiv" +msgid "active:" +msgstr "aktiv:" -#: glances/plugins/glances_mem.py:162 -msgid "total" -msgstr "gesamt" +#: glances/plugins/glances_mem.py:162 glances/plugins/glances_memswap.py:127 +msgid "total:" +msgstr "gesamt:" #: glances/plugins/glances_mem.py:168 -msgid "inactive" -msgstr "inaktiv" +msgid "inactive:" +msgstr "inaktiv:" -#: glances/plugins/glances_mem.py:175 -msgid "used" -msgstr "belegt" +#: glances/plugins/glances_mem.py:175 glances/plugins/glances_memswap.py:134 +msgid "used:" +msgstr "benutzt:" #: glances/plugins/glances_mem.py:182 -msgid "buffers" -msgstr "Puffer" +msgid "buffers:" +msgstr "Puffer:" -#: glances/plugins/glances_mem.py:189 -msgid "free" -msgstr "frei" +#: glances/plugins/glances_mem.py:189 glances/plugins/glances_memswap.py:142 +msgid "free:" +msgstr "frei:" #: glances/plugins/glances_mem.py:195 -msgid "cached" -msgstr "cached" +msgid "cached:" +msgstr "cached:" #: glances/plugins/glances_memswap.py:119 msgid "SWAP" msgstr "SWAP" -#: glances/plugins/glances_memswap.py:127 -msgid "total:" -msgstr "gesamt:" - -#: glances/plugins/glances_memswap.py:134 -msgid "used:" -msgstr "benutzt:" - -#: glances/plugins/glances_memswap.py:142 -msgid "free:" -msgstr "frei:" - #: glances/plugins/glances_monitor.py:111 msgid "RUNNING" msgstr "LAUFEND" @@ -554,148 +1350,6 @@ msgstr "LAUFEND" msgid "NOT RUNNING" msgstr "NICHT LAUFEND" -#: glances/plugins/glances_now.py:52 -msgid "%Y-%m-%d %H:%M:%S" -msgstr "%d.%m.%Y %H:%M:%S" - -#: glances/plugins/glances_now.py:66 -#, python-brace-format -msgid "{0:23}" -msgstr "{0:23}" - -#: glances/plugins/glances_percpu.py:150 -msgid "PER CPU not available" -msgstr "PRO-CPU nicht möglich" - -#: glances/plugins/glances_percpu.py:156 -msgid "PER CPU" -msgstr "PRO CPU" - -#: glances/plugins/glances_processcount.py:87 -msgid "PROCESSES DISABLED (press 'z' to display)" -msgstr "PROZESS DEAKTIVIERT (drücke 'z' zum anzeigen)" - -#: glances/plugins/glances_processcount.py:96 -msgid "TASKS" -msgstr "PROZESSE" - -#: glances/plugins/glances_processcount.py:104 -msgid "thr" -msgstr "thr" - -#: glances/plugins/glances_processcount.py:109 -msgid "run" -msgstr "run" - -#: glances/plugins/glances_processcount.py:114 -msgid "slp" -msgstr "slp" - -#: glances/plugins/glances_processcount.py:117 -msgid "oth" -msgstr "oth" - -#: glances/plugins/glances_processcount.py:126 -msgid "sorted automatically" -msgstr "automatisch sortiert" - -#: glances/plugins/glances_processcount.py:128 -msgid "by" -msgstr "nach" - -#: glances/plugins/glances_processcount.py:131 -msgid "sorted by" -msgstr "sortiert nach" - -#: glances/plugins/glances_processlist.py:100 -msgid "CPU%" -msgstr "CPU %" - -#: glances/plugins/glances_processlist.py:102 -msgid "MEM%" -msgstr "RAM%" - -#: glances/plugins/glances_processlist.py:104 -msgid "VIRT" -msgstr "VIRT" - -#: glances/plugins/glances_processlist.py:106 -msgid "RES" -msgstr "RES" - -#: glances/plugins/glances_processlist.py:108 -msgid "PID" -msgstr "PID" - -#: glances/plugins/glances_processlist.py:110 -msgid "USER" -msgstr "BENUTZER" - -#: glances/plugins/glances_processlist.py:112 -msgid "NI" -msgstr "NI" - -#: glances/plugins/glances_processlist.py:114 -msgid "S" -msgstr "S" - -#: glances/plugins/glances_processlist.py:116 -msgid "TIME+" -msgstr "ZEIT+" - -#: glances/plugins/glances_processlist.py:118 -msgid "IOR/s" -msgstr "IOR/s" - -#: glances/plugins/glances_processlist.py:120 -msgid "IOW/s" -msgstr "IOW/s" - -#: glances/plugins/glances_processlist.py:122 -msgid "Command" -msgstr "Befehl" - -#: glances/plugins/glances_system.py:111 -msgid "Connected to " -msgstr "Verbunden mit " - -#: glances/plugins/glances_system.py:114 -msgid "SNMP from " -msgstr "SNMP von " - -#: glances/plugins/glances_system.py:117 -msgid "Disconnected from " -msgstr "Getrennt von " - -#: glances/plugins/glances_system.py:121 -#, python-brace-format -msgid "{0}" -msgstr "{0}" - -#: glances/plugins/glances_system.py:125 -#, python-brace-format -msgid " ({0} {1} / {2} {3})" -msgstr " ({0} {1} / {2} {3})" - -#: glances/plugins/glances_system.py:131 -#, python-brace-format -msgid " ({0} {1} {2})" -msgstr " ({0} {1} {2})" - -#: glances/plugins/glances_system.py:135 -#, python-brace-format -msgid " ({0})" -msgstr " ({0})" - -#: glances/plugins/glances_uptime.py:95 -#, python-brace-format -msgid "Uptime: {0}" -msgstr "Betriebszeit: {0}" - -#: glances/plugins/glances_batpercent.py:110 -msgid "Battery (%)" -msgstr "Batterie (%)" - #: glances/plugins/glances_network.py:183 msgid "NETWORK" msgstr "NETZWERK" @@ -724,6 +1378,109 @@ msgstr "Rx/s" msgid "Tx/s" msgstr "Tx/s" +#: glances/plugins/glances_now.py:52 +msgid "%Y-%m-%d %H:%M:%S" +msgstr "%d.%m.%Y %H:%M:%S" + +#: glances/plugins/glances_percpu.py:150 +msgid "PER CPU not available" +msgstr "PRO-CPU nicht möglich" + +#: glances/plugins/glances_percpu.py:156 +msgid "PER CPU" +msgstr "PRO CPU" + +#: glances/plugins/glances_processcount.py:87 +msgid "PROCESSES DISABLED (press 'z' to display)" +msgstr "PROZESS DEAKTIVIERT (drücke 'z' zum anzeigen)" + +#: glances/plugins/glances_processcount.py:96 +msgid "TASKS " +msgstr "PROZESSE " + +#: glances/plugins/glances_processcount.py:104 +#, python-brace-format +msgid " ({0} thr)," +msgstr " ({0} thr)," + +#: glances/plugins/glances_processcount.py:109 +#, python-brace-format +msgid " {0} run," +msgstr " {0} run," + +#: glances/plugins/glances_processcount.py:114 +#, python-brace-format +msgid " {0} slp," +msgstr " {0} slp," + +#: glances/plugins/glances_processcount.py:117 +#, python-brace-format +msgid " {0} oth " +msgstr " {0} oth " + +#: glances/plugins/glances_processcount.py:126 +msgid "sorted automatically" +msgstr "automatisch sortiert" + +#: glances/plugins/glances_processcount.py:128 +#, python-brace-format +msgid " by {0}" +msgstr " nach {0}" + +#: glances/plugins/glances_processcount.py:131 +#, python-brace-format +msgid "sorted by {0}" +msgstr "sortiert nach {0}" + +#: glances/plugins/glances_processlist.py:100 +msgid "CPU%" +msgstr "CPU %" + +#: glances/plugins/glances_processlist.py:102 +msgid "MEM%" +msgstr "RAM%" + +#: glances/plugins/glances_processlist.py:104 +msgid "VIRT" +msgstr "VIRT" + +#: glances/plugins/glances_processlist.py:106 +msgid "RES" +msgstr "RES" + +#: glances/plugins/glances_processlist.py:108 +msgid "PID" +msgstr "PID" + +#: glances/plugins/glances_processlist.py:110 +msgid "USER" +msgstr "BENUTZER" +>>>>>>> release/v2.0 + +#: glances/plugins/glances_processlist.py:112 +msgid "NI" +msgstr "NI" + +#: glances/plugins/glances_processlist.py:114 +msgid "S" +msgstr "S" + +#: glances/plugins/glances_processlist.py:116 +msgid "TIME+" +msgstr "ZEIT+" + +#: glances/plugins/glances_processlist.py:118 +msgid "IOR/s" +msgstr "IOR/s" + +#: glances/plugins/glances_processlist.py:120 +msgid "IOW/s" +msgstr "IOW/s" + +#: glances/plugins/glances_processlist.py:122 +msgid "Command" +msgstr "Befehl" + #: glances/plugins/glances_sensors.py:121 msgid "SENSORS" msgstr "SENSOREN" @@ -732,3 +1489,15 @@ msgstr "SENSOREN" #: glances/plugins/glances_sensors.py:126 msgid "°C" msgstr "°C" + +#: glances/plugins/glances_system.py:111 +msgid "Connected to " +msgstr "Verbunden mit " + +#: glances/plugins/glances_system.py:114 +msgid "SNMP from " +msgstr "SNMP von " + +#: glances/plugins/glances_system.py:117 +msgid "Disconnected from " +msgstr "Getrennt von " diff --git a/i18n/glances.pot b/i18n/glances.pot index 34dc9124..57f44c45 100644 --- a/i18n/glances.pot +++ b/i18n/glances.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2014-05-27 13:03+0200\n" +"POT-Creation-Date: 2014-06-03 16:21+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -26,6 +26,11 @@ msgstr "" msgid "Glances server is running on {0}:{1}" msgstr "" +#: glances/core/glances_stats.py:264 +#, python-brace-format +msgid "Error: Update {0} failed: {1}" +msgstr "" + #: glances/core/glances_client.py:62 #, python-brace-format msgid "Error: Couldn't create socket {0}: {1}" @@ -50,70 +55,12 @@ msgstr "" #: glances/core/glances_client.py:147 #, python-brace-format -msgid "Error: Unknown server mode ({0})" +msgid "Error: Unknown server mode: {0}" msgstr "" #: glances/core/glances_config.py:71 #, python-brace-format -msgid "Error decoding configuration file '{0}': {1}" -msgstr "" - -#: glances/core/glances_monitor_list.py:74 -#, python-format -msgid "Error reading monitored list: %s" -msgstr "" - -#: glances/core/glances_monitor_list.py:143 -msgid "Error: " -msgstr "" - -#: glances/core/glances_monitor_list.py:145 -msgid "Cannot execute command" -msgstr "" - -#: glances/core/glances_password.py:111 -#, python-format -msgid "[Info] Read password from file %s\n" -msgstr "" - -#: glances/core/glances_password.py:120 -msgid "Password: " -msgstr "" - -#: glances/core/glances_password.py:124 -msgid "Password (confirm): " -msgstr "" - -#: glances/core/glances_password.py:127 -msgid "[Error] Sorry, but passwords did not match...\n" -msgstr "" - -#: glances/core/glances_password.py:138 -msgid "Do you want to save the password? [Yes/No]: " -msgstr "" - -#: glances/core/glances_password.py:139 -msgid "Y" -msgstr "" - -#: glances/core/glances_password.py:154 -#, python-brace-format -msgid "[Warning] Cannot create Glances directory: {0}" -msgstr "" - -#: glances/core/glances_server.py:115 -#, python-format -msgid "Couldn't open socket: %s" -msgstr "" - -#: glances/core/glances_server.py:205 -#, python-format -msgid "Error: Cannot start Glances server (%s)" -msgstr "" - -#: glances/core/glances_stats.py:264 -#, python-brace-format -msgid "Error: Update {0} failed: {1}" +msgid "Error: Cannot decode configuration file '{0}': {1}" msgstr "" #: glances/core/glances_main.py:65 @@ -165,8 +112,8 @@ msgid "export stats to a CSV file" msgstr "" #: glances/core/glances_main.py:92 -#, python-format -msgid "define the client/server TCP port [default: %d]" +#, python-brace-format +msgid "define the client/server TCP port [default: {0}]" msgstr "" #: glances/core/glances_main.py:94 @@ -202,8 +149,8 @@ msgid "SNMP authentication key (only for SNMPv3)" msgstr "" #: glances/core/glances_main.py:110 -#, python-format -msgid "set refresh time in seconds [default: %s sec]" +#, python-brace-format +msgid "set refresh time in seconds [default: {0} sec]" msgstr "" #: glances/core/glances_main.py:112 @@ -222,9 +169,66 @@ msgstr "" msgid "Enter the Glances server password" msgstr "" +#: glances/core/glances_monitor_list.py:74 +#, python-brace-format +msgid "Error: Cannot read monitored list: {0}" +msgstr "" + +#: glances/core/glances_monitor_list.py:143 +msgid "Error: " +msgstr "" + +#: glances/core/glances_monitor_list.py:145 +msgid "Cannot execute command" +msgstr "" + +#: glances/core/glances_password.py:111 +#, python-brace-format +msgid "Info: Read password from file: {0}" +msgstr "" + +#: glances/core/glances_password.py:120 +msgid "Password: " +msgstr "" + +#: glances/core/glances_password.py:124 +msgid "Password (confirm): " +msgstr "" + +#: glances/core/glances_password.py:127 +msgid "Error: Sorry, but passwords did not match..." +msgstr "" + +#: glances/core/glances_password.py:138 +msgid "Do you want to save the password? [Yes/No]: " +msgstr "" + +#: glances/core/glances_password.py:139 +msgid "Y" +msgstr "" + +#: glances/core/glances_password.py:154 +#, python-brace-format +msgid "Warning: Cannot create Glances directory: {0}" +msgstr "" + +#: glances/core/glances_server.py:115 +#, python-brace-format +msgid "Error: Couldn't open socket: {0}" +msgstr "" + +#: glances/core/glances_server.py:205 +#, python-brace-format +msgid "Error: Cannot start Glances server: {0}" +msgstr "" + +#: glances/outputs/glances_curses.py:61 +msgid "Error: Cannot init the curses library.\n" +msgstr "" + #: glances/outputs/glances_csv.py:48 #, python-brace-format -msgid "Cannot create the CSV file: {0}" +msgid "Error: Cannot create the CSV file: {0}" msgstr "" #: glances/outputs/glances_csv.py:51 @@ -232,8 +236,9 @@ msgstr "" msgid "Stats dumped to CSV file: {0}" msgstr "" -#: glances/outputs/glances_curses.py:61 -msgid "Error: Cannot init the curses library.\n" +#: glances/plugins/glances_uptime.py:95 +#, python-brace-format +msgid "Uptime: {0}" msgstr "" #: glances/plugins/glances_alert.py:78 @@ -245,12 +250,12 @@ msgid "Warning or critical alerts" msgstr "" #: glances/plugins/glances_alert.py:86 -#, python-format -msgid "(lasts %s entries)" +#, python-brace-format +msgid " (lasts {0} entries)" msgstr "" #: glances/plugins/glances_alert.py:88 -msgid "(one entry)" +msgid " (one entry)" msgstr "" #: glances/plugins/glances_alert.py:102 @@ -258,7 +263,17 @@ msgid " (ongoing)" msgstr "" #: glances/plugins/glances_alert.py:108 -msgid "on" +#, python-brace-format +msgid "{0} on {1}" +msgstr "" + +#: glances/plugins/glances_alert.py:117 +#, python-brace-format +msgid " (Min:{0:.1f} Mean:{1:.1f} Max:{2:.1f})" +msgstr "" + +#: glances/plugins/glances_batpercent.py:107 +msgid "Battery (%)" msgstr "" #: glances/plugins/glances_cpu.py:123 @@ -281,11 +296,11 @@ msgstr "" msgid "system:" msgstr "" -#: glances/plugins/glances_cpu.py:158 glances/plugins/glances_percpu.py:188 +#: glances/plugins/glances_cpu.py:158 msgid "iowait:" msgstr "" -#: glances/plugins/glances_cpu.py:166 +#: glances/plugins/glances_cpu.py:166 glances/plugins/glances_percpu.py:188 msgid "idle:" msgstr "" @@ -318,7 +333,8 @@ msgid "Total" msgstr "" #: glances/plugins/glances_help.py:68 -msgid "with psutil" +#, python-brace-format +msgid " with psutil {0}" msgstr "" #: glances/plugins/glances_help.py:77 @@ -462,7 +478,7 @@ msgid "z" msgstr "" #: glances/plugins/glances_help.py:119 -msgid "Enable/Disable processes stats" +msgid "Enable/disable processes stats" msgstr "" #: glances/plugins/glances_help.py:122 @@ -479,7 +495,7 @@ msgstr "" #: glances/plugins/glances_load.py:127 #, python-brace-format -msgid "{0:>5}-core" +msgid "{0}-core" msgstr "" #: glances/plugins/glances_load.py:132 @@ -499,49 +515,37 @@ msgid "MEM" msgstr "" #: glances/plugins/glances_mem.py:155 -msgid "active" +msgid "active:" msgstr "" -#: glances/plugins/glances_mem.py:162 -msgid "total" +#: glances/plugins/glances_mem.py:162 glances/plugins/glances_memswap.py:127 +msgid "total:" msgstr "" #: glances/plugins/glances_mem.py:168 -msgid "inactive" +msgid "inactive:" msgstr "" -#: glances/plugins/glances_mem.py:175 -msgid "used" +#: glances/plugins/glances_mem.py:175 glances/plugins/glances_memswap.py:134 +msgid "used:" msgstr "" #: glances/plugins/glances_mem.py:182 -msgid "buffers" +msgid "buffers:" msgstr "" -#: glances/plugins/glances_mem.py:189 -msgid "free" +#: glances/plugins/glances_mem.py:189 glances/plugins/glances_memswap.py:142 +msgid "free:" msgstr "" #: glances/plugins/glances_mem.py:195 -msgid "cached" +msgid "cached:" msgstr "" #: glances/plugins/glances_memswap.py:119 msgid "SWAP" msgstr "" -#: glances/plugins/glances_memswap.py:127 -msgid "total:" -msgstr "" - -#: glances/plugins/glances_memswap.py:134 -msgid "used:" -msgstr "" - -#: glances/plugins/glances_memswap.py:142 -msgid "free:" -msgstr "" - #: glances/plugins/glances_monitor.py:111 msgid "RUNNING" msgstr "" @@ -550,13 +554,36 @@ msgstr "" msgid "NOT RUNNING" msgstr "" -#: glances/plugins/glances_now.py:52 -msgid "%Y-%m-%d %H:%M:%S" +#: glances/plugins/glances_network.py:183 +msgid "NETWORK" msgstr "" -#: glances/plugins/glances_now.py:66 -#, python-brace-format -msgid "{0:23}" +#: glances/plugins/glances_network.py:189 +msgid "Rx+Tx" +msgstr "" + +#: glances/plugins/glances_network.py:193 +msgid "Rx" +msgstr "" + +#: glances/plugins/glances_network.py:195 +msgid "Tx" +msgstr "" + +#: glances/plugins/glances_network.py:201 +msgid "Rx+Tx/s" +msgstr "" + +#: glances/plugins/glances_network.py:204 +msgid "Rx/s" +msgstr "" + +#: glances/plugins/glances_network.py:206 +msgid "Tx/s" +msgstr "" + +#: glances/plugins/glances_now.py:52 +msgid "%Y-%m-%d %H:%M:%S" msgstr "" #: glances/plugins/glances_percpu.py:150 @@ -572,23 +599,27 @@ msgid "PROCESSES DISABLED (press 'z' to display)" msgstr "" #: glances/plugins/glances_processcount.py:96 -msgid "TASKS" +msgid "TASKS " msgstr "" #: glances/plugins/glances_processcount.py:104 -msgid "thr" +#, python-brace-format +msgid " ({0} thr)," msgstr "" #: glances/plugins/glances_processcount.py:109 -msgid "run" +#, python-brace-format +msgid " {0} run," msgstr "" #: glances/plugins/glances_processcount.py:114 -msgid "slp" +#, python-brace-format +msgid " {0} slp," msgstr "" #: glances/plugins/glances_processcount.py:117 -msgid "oth" +#, python-brace-format +msgid " {0} oth " msgstr "" #: glances/plugins/glances_processcount.py:126 @@ -596,11 +627,13 @@ msgid "sorted automatically" msgstr "" #: glances/plugins/glances_processcount.py:128 -msgid "by" +#, python-brace-format +msgid " by {0}" msgstr "" #: glances/plugins/glances_processcount.py:131 -msgid "sorted by" +#, python-brace-format +msgid "sorted by {0}" msgstr "" #: glances/plugins/glances_processlist.py:100 @@ -651,6 +684,15 @@ msgstr "" msgid "Command" msgstr "" +#: glances/plugins/glances_sensors.py:121 +msgid "SENSORS" +msgstr "" + +#: glances/plugins/glances_sensors.py:124 +#: glances/plugins/glances_sensors.py:126 +msgid "°C" +msgstr "" + #: glances/plugins/glances_system.py:111 msgid "Connected to " msgstr "" @@ -662,69 +704,3 @@ msgstr "" #: glances/plugins/glances_system.py:117 msgid "Disconnected from " msgstr "" - -#: glances/plugins/glances_system.py:121 -#, python-brace-format -msgid "{0}" -msgstr "" - -#: glances/plugins/glances_system.py:125 -#, python-brace-format -msgid " ({0} {1} / {2} {3})" -msgstr "" - -#: glances/plugins/glances_system.py:131 -#, python-brace-format -msgid " ({0} {1} {2})" -msgstr "" - -#: glances/plugins/glances_system.py:135 -#, python-brace-format -msgid " ({0})" -msgstr "" - -#: glances/plugins/glances_uptime.py:95 -#, python-brace-format -msgid "Uptime: {0}" -msgstr "" - -#: glances/plugins/glances_batpercent.py:110 -msgid "Battery (%)" -msgstr "" - -#: glances/plugins/glances_network.py:183 -msgid "NETWORK" -msgstr "" - -#: glances/plugins/glances_network.py:189 -msgid "Rx+Tx" -msgstr "" - -#: glances/plugins/glances_network.py:193 -msgid "Rx" -msgstr "" - -#: glances/plugins/glances_network.py:195 -msgid "Tx" -msgstr "" - -#: glances/plugins/glances_network.py:201 -msgid "Rx+Tx/s" -msgstr "" - -#: glances/plugins/glances_network.py:204 -msgid "Rx/s" -msgstr "" - -#: glances/plugins/glances_network.py:206 -msgid "Tx/s" -msgstr "" - -#: glances/plugins/glances_sensors.py:121 -msgid "SENSORS" -msgstr "" - -#: glances/plugins/glances_sensors.py:124 -#: glances/plugins/glances_sensors.py:126 -msgid "°C" -msgstr "" diff --git a/man/glances.1 b/man/glances.1 index aca27247..08b87183 100644 --- a/man/glances.1 +++ b/man/glances.1 @@ -1,83 +1,114 @@ -.TH glances 1 "January, 2014" "version 1.7.4" "USER COMMANDS" +<<<<<<< HEAD +.TH glances 1 "May, 2014" "version 1.7.7" "USER COMMANDS" +======= +.TH glances 1 "June, 2014" "version 2.0" "USER COMMANDS" +>>>>>>> release/v2.0 .SH NAME -glances \- A cross-platform curses-based monitoring tool +glances \- A cross-platform curses-based system monitoring tool .SH SYNOPSIS .B glances -[\-bdehmnrsvyz1] [\-B bind] [\-c server] [\-C conffile] [\-p port] [\-P password] [--password] [\-t refresh] [\-f file] [\-o output] +<<<<<<< HEAD +[\-bdehmnrsvyz1] [\-B bind] [\-c server] [\-C conffile] [\-p port] [\-P password] [\-\-password] [\-t refresh] [\-f file] [\-o output] +======= +.RI [ OPTIONS ] +>>>>>>> release/v2.0 .SH DESCRIPTION -Glances is a free (LGPL) cross-platform curses-based monitoring tool which aims to present a maximum of information -in a minimum of space, ideally to fit in a classical 80x24 terminal or higher to have additionnal information. +Glances is a free (LGPL) cross-platform curses-based system monitoring tool which +aims to present a maximum of information in a minimum of space, ideally to fit in +a classical 80x24 terminal or higher to have additionnal information. It can adapt +dynamically the displayed information depending on the terminal size. .PP -Glances can adapt dynamically the displayed information depending on the terminal size. It can also -work in a client/server mode for remote monitoring. +Glances can also work in client/server mode. Remote monitoring could be done via +terminal or web interface. .PP -This tool is written in Python and uses the psutil library to fetch the statistical values from key elements, -like CPU, load average, memory, network, disks, file systems, processes, etc. +This tool is written in Python and uses the psutil library to fetch the statistical +values from key elements, like CPU, load average, memory, network, disks, file +systems, processes and so on. .SH COMMAND-LINE OPTIONS The command-line options are the following: .TP -.B \-b -Display network rate in Byte per second (default: bit per second) +.B \-h, \-\-help +display the help and exit .TP -.B \-B @IP|HOST -Bind server to the given IPv4/IPv6 address or hostname +.B \-V, \-\-version +show program's version number and exit .TP -.B \-c @IP|HOST -Connect to a Glances server by IPv4/IPv6 address or hostname +.B \-b, \-\-byte +display network rate in byte per second [default: bit per second] .TP -.B \-C FILE -Path to the configuration file +.B \-B BIND_ADDRESS, \-\-bind BIND_ADDRESS +bind server to the given IPv4/IPv6 address or hostname .TP -.B \-d -Disable disk I/O module +.B \-c CLIENT, \-\-client CLIENT +connect to a Glances server by IPv4/IPv6 address or hostname .TP -.B \-e -Enable sensors module (requires pysensors, Linux-only) +.B \-C CONF_FILE, \-\-config CONF_FILE +path to the configuration file .TP -.B \-f FILE -Set the HTML output folder or CSV file +<<<<<<< HEAD +.B \-f FOLDER +Set the HTML or CSV output folder +======= +.B \-\-disable-bold +disable bold mode in the terminal +>>>>>>> release/v2.0 .TP -.B \-h -Display the help and exit +.B \-\-disable-diskio +disable disk I/O module .TP -.B \-m -Disable mount module +.B \-\-disable-fs +disable file system module .TP -.B \-n -Disable network module +.B \-\-disable-network +disable network module .TP -.B \-o OUTPUT -Define additional output (available: HTML or CSV) +.B \-\-disable-network +disable network module .TP -.B \-p PORT -Define the client/server TCP port (default: 61209) +.B \-\-disable-sensors +disable sensors module .TP -.B \-P PASSWORD -Define a client/server password +.B \-\-disable-process +disable process module +.TP +.B \-\-disable-log +disable log module +.TP +.B \-\-output-csv OUTPUT_CSV +export stats to a CSV file +.TP +.B \-p PORT, \-\-port PORT +define the client/server TCP port [default: 61209] .TP .B \-\-password -Define a client/server password from the prompt +define a client/server password from the prompt or file .TP -.B \-r -Disable process list (for low CPU consumption) +.B \-s, \-\-server +run Glances in server mode .TP -.B \-s -Run Glances in server mode +.B \-\-snmp-community SNMP_COMMUNITY +SNMP community .TP -.B \-t SECONDS -Set refresh time in seconds (default: 3 sec) +.B \-\-snmp-port SNMP_PORT +SNMP port .TP -.B \-v -Display the version and exit +.B \-\-snmp-version SNMP_VERSION +SNMP version (1, 2c or 3) .TP -.B \-y -Enable hddtemp module (requires hddtemp) +.B \-\-snmp-user SNMP_USER +SNMP username (only for SNMPv3) .TP -.B \-z -Do not use the bold color attribute +.B \-\-snmp-auth SNMP_AUTH +SNMP authentication key (only for SNMPv3) .TP -.B \-1 -Start Glances in per-CPU mode +.B \-t TIME, \-\-time TIME +set refresh time in seconds [default: 3 sec] +.TP +.B \-w, \-\-webserver +run Glances in Web server mode +.TP +.B \-1, \-\-percpu +start Glances in per CPU mode .SH INTERACTIVE COMMANDS You can use the following keys while in Glances: .TP @@ -118,7 +149,7 @@ Sort processes by name Quit .TP .B s -Show/hide sensors stats (only available with \-e flag) +Show/hide sensors stats .TP .B t View network I/O as combination @@ -132,8 +163,11 @@ Delete finished warning log messages .B x Delete finished warning and critical log messages .TP -.B y -Show/hide hddtemp stats (only available with \-y flag) +.B z +Show/hide processes stats +.TP +.B z +Show/hide processes list (for low CPU consumption) .TP .B 1 Switch between global CPU and per-CPU stats diff --git a/setup.py b/setup.py index 4bb44766..7fae26f2 100755 --- a/setup.py +++ b/setup.py @@ -55,7 +55,8 @@ setup( extras_require={ 'WEB': ['bottle'], 'SENSORS': ['py3sensors'], - 'BATINFO': ['batinfo'] + 'BATINFO': ['batinfo'], + 'SNMP': ['pysnmp'] }, packages=['glances'], include_package_data=True, @@ -74,6 +75,7 @@ setup( 'Programming Language :: Python :: 2.6', 'Programming Language :: Python :: 2.7', 'Programming Language :: Python :: 3', + 'Programming Language :: Python :: 3.2', 'Programming Language :: Python :: 3.3', 'Programming Language :: Python :: 3.4' ] diff --git a/unitest.py b/unitest.py index 91437941..d01693c7 100755 --- a/unitest.py +++ b/unitest.py @@ -17,43 +17,35 @@ # # You should have received a copy of the GNU Lesser General Public License # along with this program. If not, see . -""" -Glances unitary tests suite... -""" -import os -import sys -import time +"""Glances unitary tests suite.""" + import gettext import locale +import sys +import time import unittest from glances.core.glances_globals import ( - __appname__, - __version__, - is_bsd, + appname, is_linux, - is_mac, - is_py3, - is_windows, - sys_prefix, - work_path + version ) # Global variables -#================= +# ================= # Unitary test is only available from a GNU/Linus machine if not is_linux: print('ERROR: Unitaries tests should be ran on GNU/Linux operating system') sys.exit(2) else: - print('{} {} {}'.format('Unitary tests for', __appname__, __version__)) + print('Unitary tests for {0} {1}'.format(appname, version)) # Import local settings from glances.core.glances_globals import gettext_domain, locale_dir locale.setlocale(locale.LC_ALL, '') -gettext.install(gettext_domain, locale_dir) +gettext.install(gettext_domain, locale_dir) # Init Glances core from glances.core.glances_main import GlancesMain @@ -66,26 +58,23 @@ if not core.is_standalone(): from glances.core.glances_stats import GlancesStats stats = GlancesStats() -# Unitest class -#============== -class testGlances(unittest.TestCase): - """ - Test glances class - """ +# Unitest class +# ============== + +class TestGlances(unittest.TestCase): + + """Test Glances class.""" def setUp(self): - """ - This function is called *every time* before test_* - """ - print('\n' + '='*78) + """The function is called *every time* before test_*.""" + print('\n' + '=' * 78) def test_000_update(self): - """ - Update stats (mandatory step for all the stats) - The update is made twice (for rate computation) - """ + """Update stats (mandatory step for all the stats). + The update is made twice (for rate computation). + """ print('INFO: [TEST_000] Test the stats update function') try: stats.update() @@ -98,134 +87,104 @@ class testGlances(unittest.TestCase): except: print('ERROR: Stats update failed') self.assertTrue(False) - + self.assertTrue(True) def test_001_plugins(self): - """ - Check mandatory plugins - """ - - plug_to_check = [ 'system', 'cpu', 'load', 'mem', 'memswap', 'network', 'diskio', 'fs' ] - print('INFO: [TEST_001] Check the mandatory plugins list: %s' % ', '.join(plug_to_check)) - plug_list = stats.getAllPlugins() - for p in plug_to_check: - self.assertTrue(p in plug_list) + """Check mandatory plugins.""" + plugins_to_check = ['system', 'cpu', 'load', 'mem', 'memswap', 'network', 'diskio', 'fs'] + print('INFO: [TEST_001] Check the mandatory plugins list: %s' % ', '.join(plugins_to_check)) + plugins_list = stats.getAllPlugins() + for plugin in plugins_to_check: + self.assertTrue(plugin in plugins_list) def test_002_cpu(self): - """ - Check SYSTEM plugin - """ - - stats_to_check = [ 'hostname', 'os_name' ] + """Check SYSTEM plugin.""" + stats_to_check = ['hostname', 'os_name'] print('INFO: [TEST_002] Check SYSTEM stats: %s' % ', '.join(stats_to_check)) stats_grab = stats.get_plugin('system').get_raw() - for s in stats_to_check: + for stat in stats_to_check: # Check that the key exist - self.assertTrue(stats_grab.has_key(s), msg='Can not find key: %s' % s) + self.assertTrue(stat in stats_grab, msg='Cannot find key: %s' % stat) print('INFO: SYSTEM stats: %s' % stats_grab) def test_003_cpu(self): - """ - Check CPU plugin - """ - - stats_to_check = [ 'system', 'user', 'idle' ] + """Check CPU plugin.""" + stats_to_check = ['system', 'user', 'idle'] print('INFO: [TEST_003] Check mandatory CPU stats: %s' % ', '.join(stats_to_check)) stats_grab = stats.get_plugin('cpu').get_raw() - for s in stats_to_check: + for stat in stats_to_check: # Check that the key exist - self.assertTrue(stats_grab.has_key(s), msg='Can not find key: %s' % s) + self.assertTrue(stat in stats_grab, msg='Cannot find key: %s' % stat) # Check that % is > 0 and < 100 - self.assertGreaterEqual(stats_grab[s], 0) - self.assertLessEqual(stats_grab[s], 100) + self.assertGreaterEqual(stats_grab[stat], 0) + self.assertLessEqual(stats_grab[stat], 100) print('INFO: CPU stats: %s' % stats_grab) def test_004_load(self): - """ - Check LOAD plugin - """ - - stats_to_check = [ 'cpucore', 'min1', 'min5', 'min15' ] + """Check LOAD plugin.""" + stats_to_check = ['cpucore', 'min1', 'min5', 'min15'] print('INFO: [TEST_004] Check LOAD stats: %s' % ', '.join(stats_to_check)) stats_grab = stats.get_plugin('load').get_raw() - for s in stats_to_check: + for stat in stats_to_check: # Check that the key exist - self.assertTrue(stats_grab.has_key(s), msg='Can not find key: %s' % s) + self.assertTrue(stat in stats_grab, msg='Cannot find key: %s' % stat) # Check that % is > 0 - self.assertGreaterEqual(stats_grab[s], 0) + self.assertGreaterEqual(stats_grab[stat], 0) print('INFO: LOAD stats: %s' % stats_grab) def test_005_mem(self): - """ - Check MEM plugin - """ - - stats_to_check = [ 'available', 'used', 'free', 'total' ] + """Check MEM plugin.""" + stats_to_check = ['available', 'used', 'free', 'total'] print('INFO: [TEST_005] Check MEM stats: %s' % ', '.join(stats_to_check)) stats_grab = stats.get_plugin('mem').get_raw() - for s in stats_to_check: + for stat in stats_to_check: # Check that the key exist - self.assertTrue(stats_grab.has_key(s), msg='Can not find key: %s' % s) + self.assertTrue(stat in stats_grab, msg='Cannot find key: %s' % stat) # Check that % is > 0 - self.assertGreaterEqual(stats_grab[s], 0) + self.assertGreaterEqual(stats_grab[stat], 0) print('INFO: MEM stats: %s' % stats_grab) def test_006_swap(self): - """ - Check MEMSWAP plugin - """ - - stats_to_check = [ 'used', 'free', 'total' ] + """Check MEMSWAP plugin.""" + stats_to_check = ['used', 'free', 'total'] print('INFO: [TEST_006] Check SWAP stats: %s' % ', '.join(stats_to_check)) stats_grab = stats.get_plugin('memswap').get_raw() - for s in stats_to_check: + for stat in stats_to_check: # Check that the key exist - self.assertTrue(stats_grab.has_key(s), msg='Can not find key: %s' % s) + self.assertTrue(stat in stats_grab, msg='Cannot find key: %s' % stat) # Check that % is > 0 - self.assertGreaterEqual(stats_grab[s], 0) + self.assertGreaterEqual(stats_grab[stat], 0) print('INFO: SWAP stats: %s' % stats_grab) def test_007_network(self): - """ - Check NETWORK plugin - """ - + """Check NETWORK plugin.""" print('INFO: [TEST_007] Check NETWORK stats') stats_grab = stats.get_plugin('network').get_raw() self.assertTrue(type(stats_grab) is list, msg='Network stats is not a list') print('INFO: NETWORK stats: %s' % stats_grab) def test_008_diskio(self): - """ - Check DISKIO plugin - """ - + """Check DISKIO plugin.""" print('INFO: [TEST_008] Check DiskIO stats') stats_grab = stats.get_plugin('diskio').get_raw() self.assertTrue(type(stats_grab) is list, msg='DiskIO stats is not a list') print('INFO: diskio stats: %s' % stats_grab) def test_009_fs(self): - """ - Check FileSystem plugin - """ - - stats_to_check = [ ] + """Check File System plugin.""" + # stats_to_check = [ ] print('INFO: [TEST_009] Check FS stats') stats_grab = stats.get_plugin('fs').get_raw() self.assertTrue(type(stats_grab) is list, msg='FileSystem stats is not a list') print('INFO: FS stats: %s' % stats_grab) def test_010_processes(self): - """ - Check Process plugin - """ - - stats_to_check = [ ] + """Check Process plugin.""" + # stats_to_check = [ ] print('INFO: [TEST_010] Check PROCESS stats') stats_grab = stats.get_plugin('processcount').get_raw() - total = stats_grab['total'] + # total = stats_grab['total'] self.assertTrue(type(stats_grab) is dict, msg='Process count stats is not a dict') print('INFO: PROCESS count stats: %s' % stats_grab) stats_grab = stats.get_plugin('processlist').get_raw()