Move GUI files to separate project
|
|
@ -10,7 +10,6 @@ addons:
|
|||
apt:
|
||||
packages:
|
||||
- python-dev
|
||||
- qt4-dev-tools
|
||||
# command to install dependencies
|
||||
install:
|
||||
- pip install -r requirements.txt
|
||||
|
|
|
|||
|
|
@ -12,11 +12,6 @@ include linkcheck/HtmlParser/htmllex.l
|
|||
include linkcheck/HtmlParser/htmlparse.y
|
||||
include linkcheck/HtmlParser/*.h
|
||||
include linkcheck/HtmlParser/fixincludes.awk
|
||||
include linkcheck/gui/Makefile
|
||||
include linkcheck/gui/rc/Makefile
|
||||
include linkcheck/gui/rc/*.png
|
||||
include linkcheck/gui/rc/*.qrc
|
||||
include linkcheck/gui/ui/*.ui
|
||||
include po/*.po po/*.mo po/*.pot po/Makefile
|
||||
include doc/*.example doc/*.txt
|
||||
include doc/html/*.ico
|
||||
|
|
|
|||
33
Makefile
|
|
@ -18,33 +18,14 @@ DEBORIGFILE:=$(DEBUILDDIR)/$(LAPPNAME)_$(VERSION).orig.tar.$(ARCHIVE_SOURCE_EXT)
|
|||
DEBPACKAGEDIR:=$(DEBUILDDIR)/$(APPNAME)-$(VERSION)
|
||||
FILESCHECK_URL:=http://localhost/~calvin/
|
||||
SRCDIR:=${HOME}/src
|
||||
PY_FILES_DIRS:=linkcheck tests *.py linkchecker linkchecker-gui cgi-bin config doc/examples scripts
|
||||
PY_FILES_DIRS:=linkcheck tests *.py linkchecker cgi-bin config doc/examples scripts
|
||||
MYPY_FILES_DIRS:=linkcheck/HtmlParser linkcheck/checker \
|
||||
linkcheck/cache linkcheck/configuration linkcheck/director \
|
||||
linkcheck/htmlutil linkcheck/logger linkcheck/network \
|
||||
linkcheck/bookmarks linkcheck/plugins linkcheck/parser \
|
||||
linkcheck/gui/__init__.py \
|
||||
linkcheck/gui/checker.py \
|
||||
linkcheck/gui/contextmenu.py \
|
||||
linkcheck/gui/debug.py \
|
||||
linkcheck/gui/editor.py \
|
||||
linkcheck/gui/editor_qsci.py \
|
||||
linkcheck/gui/editor_qt.py \
|
||||
linkcheck/gui/lineedit.py \
|
||||
linkcheck/gui/help.py \
|
||||
linkcheck/gui/logger.py \
|
||||
linkcheck/gui/options.py \
|
||||
linkcheck/gui/properties.py \
|
||||
linkcheck/gui/settings.py \
|
||||
linkcheck/gui/statistics.py \
|
||||
linkcheck/gui/syntax.py \
|
||||
linkcheck/gui/updater.py \
|
||||
linkcheck/gui/urlmodel.py \
|
||||
linkcheck/gui/urlsave.py \
|
||||
$(filter-out %2.py,$(wildcard linkcheck/*.py)) \
|
||||
cgi-bin/lc.wsgi \
|
||||
linkchecker \
|
||||
linkchecker-gui \
|
||||
*.py
|
||||
|
||||
TESTS ?= tests
|
||||
|
|
@ -74,10 +55,10 @@ all:
|
|||
clean:
|
||||
-$(PYTHON) setup.py clean --all
|
||||
rm -f $(LAPPNAME)-out.* *-stamp*
|
||||
$(MAKE) -C doc/html clean
|
||||
$(MAKE) -C linkcheck/HtmlParser clean
|
||||
rm -f linkcheck/network/_network*.so
|
||||
find . -name '*.py[co]' -exec rm -f {} \;
|
||||
find . -name '*.bak' -exec rm -f {} \;
|
||||
find . -depth -name '__pycache__' -exec rm -rf {} \;
|
||||
|
||||
distclean: clean
|
||||
|
|
@ -97,7 +78,6 @@ locale:
|
|||
|
||||
# to build in the current directory
|
||||
localbuild: MANIFEST locale
|
||||
$(MAKE) -C doc/html
|
||||
$(MAKE) -C linkcheck/HtmlParser
|
||||
$(PYTHON) setup.py build
|
||||
cp -f build/lib.$(PLATFORM)-$(PYVER)*/linkcheck/HtmlParser/htmlsax*.so linkcheck/HtmlParser
|
||||
|
|
@ -193,7 +173,7 @@ test: localbuild
|
|||
pyflakes:
|
||||
pyflakes $(PY_FILES_DIRS) 2>&1 | \
|
||||
grep -v "local variable 'dummy' is assigned to but never used" | \
|
||||
grep -v -E "'(PyQt4|biplist|setuptools|win32com|find_executable|parse_sitemap|parse_sitemapindex|parse_bookmark_data|parse_bookmark_file|wsgiref|pyftpdlib|linkchecker_rc)' imported but unused" | \
|
||||
grep -v -E "'(biplist|setuptools|win32com|find_executable|parse_sitemap|parse_sitemapindex|parse_bookmark_data|parse_bookmark_file|wsgiref|pyftpdlib|linkchecker_rc)' imported but unused" | \
|
||||
grep -v "undefined name '_'" | \
|
||||
grep -v "undefined name '_n'" | cat
|
||||
|
||||
|
|
@ -217,17 +197,14 @@ dnsdiff:
|
|||
changelog:
|
||||
github-changelog $(DRYRUN) $(GITUSER) $(GITREPO) doc/changelog.txt
|
||||
|
||||
gui:
|
||||
$(MAKE) -C linkcheck/gui
|
||||
|
||||
count:
|
||||
@sloccount linkchecker linkchecker-gui linkcheck tests
|
||||
@sloccount linkchecker linkcheck tests
|
||||
|
||||
# run eclipse ide
|
||||
ide:
|
||||
eclipse -data $(CURDIR)/..
|
||||
|
||||
.PHONY: test changelog gui count pyflakes ide login upload all clean distclean
|
||||
.PHONY: test changelog count pyflakes ide login upload all clean distclean
|
||||
.PHONY: pep8 cleandeb locale localbuild deb diff dnsdiff sign
|
||||
.PHONY: filescheck update-copyright releasecheck check register announce
|
||||
.PHONY: chmod dist release homepage
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ Features
|
|||
- honors robots.txt exclusion protocol
|
||||
- Cookie support
|
||||
- HTML5 support
|
||||
- a command line, GUI and web interface
|
||||
- a command line and web interface
|
||||
- various check plugins available, eg. HTML syntax and antivirus checks.
|
||||
|
||||
Installation
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
# Sample configuration file; see the linkcheckerrc(5) man page or
|
||||
# execute linkchecker -h for help on these options.
|
||||
# Commandline or GUI options override these settings.
|
||||
# Commandline options override these settings.
|
||||
|
||||
##################### output configuration ##########################
|
||||
[output]
|
||||
|
|
@ -21,10 +21,6 @@
|
|||
|
||||
|
||||
##################### logger configuration ##########################
|
||||
# Note that the logger configuration is ignored by the linkchecker-gui
|
||||
# program. Results in the GUI can be saved to a file with the command
|
||||
# File -> Save results.
|
||||
#
|
||||
# logger output part names:
|
||||
# all For all parts
|
||||
# realurl The full url link
|
||||
|
|
|
|||
|
|
@ -1,10 +1,9 @@
|
|||
HTMLDIR:=web/media
|
||||
MANHTMLFILES:= \
|
||||
$(HTMLDIR)/man1/linkchecker.1.html \
|
||||
$(HTMLDIR)/man5/linkcheckerrc.5.html \
|
||||
$(HTMLDIR)/man1/linkchecker-gui.1.html
|
||||
$(HTMLDIR)/man5/linkcheckerrc.5.html
|
||||
|
||||
MANFILES:=linkchecker.1 linkcheckerrc.5 linkchecker-gui.1
|
||||
MANFILES:=linkchecker.1 linkcheckerrc.5
|
||||
LOCALES:=en de
|
||||
|
||||
all:
|
||||
|
|
@ -22,10 +21,6 @@ $(HTMLDIR)/man5/linkcheckerrc.5.html: en/linkcheckerrc.5 linkcheckerrc.5.html.di
|
|||
man2html -r $< | tail -n +2 | sed 's/Time:.*//g' | sed 's@/:@/@g' > $@
|
||||
patch --no-backup-if-mismatch --quiet $@ linkcheckerrc.5.html.diff
|
||||
|
||||
$(HTMLDIR)/man1/linkchecker-gui.1.html: en/linkchecker-gui.1 linkchecker-gui.1.html.diff
|
||||
man2html -r $< | tail -n +2 | sed 's/Time:.*//g' | sed 's@/:@/@g' > $@
|
||||
patch --no-backup-if-mismatch --quiet $@ linkchecker-gui.1.html.diff
|
||||
|
||||
# check all makefiles for formatting warnings
|
||||
check:
|
||||
@t=$(shell tempfile); \
|
||||
|
|
|
|||
|
|
@ -1,30 +0,0 @@
|
|||
.\"*******************************************************************
|
||||
.\"
|
||||
.\" This file was generated with po4a. Translate the source file.
|
||||
.\"
|
||||
.\"*******************************************************************
|
||||
.TH LINKCHECKER\-GUI 1 2009\-01\-10 "LinkChecker GUI" "LinkChecker GUI Programm"
|
||||
.SH NAME
|
||||
linkchecker\-gui \- GUI\-Programm zum Prüfen von Verknüpfungen von Webseiten
|
||||
und HTML Dokumenten
|
||||
.
|
||||
.SH SYNTAX
|
||||
\fBlinkchecker\-gui\fP [\fIDatei\-oder\-URL\-oder\-Projekt\fP]
|
||||
.
|
||||
.SH BESCHREIBUNG
|
||||
Eine graphische Benutzeroberfläche, um Verknüpfungen von Webseiten und HTML
|
||||
Dokumenten zu prüfen.
|
||||
.
|
||||
.SH PROJEKTDATEIEN
|
||||
Eine Projektdatei hat die Dateierweiterung .lcp. Die Datei speichert alle
|
||||
aktiven Einstellungen und die zu prüfende URL. Projektdateien können mit dem
|
||||
Menü oder mit Drag\-And\-Drop auf das GUI\-Fenster geladen werden.
|
||||
|
||||
.SH "SIEHE AUCH"
|
||||
\fBlinkchecker\fP(1)
|
||||
.
|
||||
.SH AUTHOR
|
||||
Bastian Kleineidam <bastian.kleineidam@web.de>
|
||||
.
|
||||
.SH COPYRIGHT
|
||||
Copyright \(co 2009\-2014 Bastian Kleineidam
|
||||
|
|
@ -39,7 +39,7 @@ HTML\- und CSS\-Syntaxprüfung
|
|||
.IP \(bu
|
||||
Antivirusprüfung
|
||||
.IP \(bu
|
||||
ein Kommandozeilenprogramm, GUI und web interface
|
||||
ein Kommandozeilenprogramm und web interface
|
||||
.SH BEISPIELE
|
||||
The most common use checks the given domain recursively:
|
||||
\fBlinkchecker http://www.example.com/\fP
|
||||
|
|
@ -81,8 +81,8 @@ Lese Liste von URLs zum Prüfen von der Standardeingabe, getrennt durch
|
|||
Leerzeichen.
|
||||
.TP
|
||||
\fB\-t\fP\fINUMMER\fP, \fB\-\-threads=\fP\fINUMMER\fP
|
||||
Generiere nicht mehr als die angegebene Anzahl von Threads. Die Standardanzahl von Threads ist 10.
|
||||
Um Threads zu deaktivieren, geben Sie eine nicht positive Nummer an.
|
||||
Generate no more than the given number of threads. Default number of threads
|
||||
is 10. To disable threading specify a non\-positive number.
|
||||
.TP
|
||||
\fB\-V\fP, \fB\-\-version\fP
|
||||
Gebe die Version aus und beende das Programm.
|
||||
|
|
@ -94,7 +94,7 @@ Print available check plugins and exit.
|
|||
.TP
|
||||
\fB\-D\fP\fINAME\fP, \fB\-\-debug=\fP\fINAME\fP
|
||||
Gebe Testmeldungen aus für den angegebenen Logger. Verfügbare Logger sind
|
||||
\fBcmdline\fP, \fBchecking\fP,\fBcache\fP, \fBgui\fP, \fBdns\fP und \fBall\fP. Die Angabe
|
||||
\fBcmdline\fP, \fBchecking\fP,\fBcache\fP, \fBdns\fP, \fBplugins\fP und \fBall\fP. Die Angabe
|
||||
\fBall\fP ist ein Synonym für alle verfügbaren Logger. Diese Option kann
|
||||
mehrmals angegeben werden, um mit mehr als einem Logger zu testen. Um
|
||||
akkurate Ergebnisse zu erzielen, werden Threads deaktiviert.
|
||||
|
|
|
|||
|
|
@ -47,8 +47,8 @@ bewirkt unendliche Rekursion. Standard Tiefe ist unendlich.
|
|||
Kommandozeilenoption: \fB\-\-recursion\-level\fP
|
||||
.TP
|
||||
\fBthreads=\fP\fINUMBER\fP
|
||||
Generiere nicht mehr als die angegebene Anzahl von Threads. Die Standardanzahl von Threads ist 10.
|
||||
Um Threads zu deaktivieren, geben Sie eine nicht positive Nummer an.
|
||||
Generate no more than the given number of threads. Default number of threads
|
||||
is 10. To disable threading specify a non\-positive number.
|
||||
.br
|
||||
Kommandozeilenoption: \fB\-\-threads\fP
|
||||
.TP
|
||||
|
|
@ -82,8 +82,7 @@ Kommandozeilenoption: keine
|
|||
\fBmaxrunseconds=\fP\fINUMBER\fP
|
||||
Hört nach der angegebenen Anzahl von Sekunden auf, neue URLs zu prüfen. Dies
|
||||
ist dasselbe als wenn der Benutzer nach der gegebenen Anzahl von Sekunden
|
||||
stoppt (durch Drücken von Strg\-C oder Klicken auf den Knopf Abbrechen im
|
||||
GUI).
|
||||
stoppt (durch Drücken von Strg\-C).
|
||||
.br
|
||||
Standard ist nicht zu stoppen bis alle URLs geprüft sind.
|
||||
.br
|
||||
|
|
@ -111,8 +110,8 @@ Ausdruck entsprechen.
|
|||
Kommandozeilenoption: \fB\-\-ignore\-url\fP
|
||||
.TP
|
||||
\fBignorewarnings=\fP\fINAME\fP[\fB,\fP\fINAME\fP...]
|
||||
Ignoriere die kommagetrennte Liste von Warnungen. Siehe \fBWARNUNGEN\fP für die
|
||||
Liste von erkannten Warnungen.
|
||||
Ignore the comma\-separated list of warnings. See \fBWARNINGS\fP for the list of
|
||||
supported warnings.
|
||||
.br
|
||||
Kommandozeilenoption: keine
|
||||
.TP
|
||||
|
|
@ -167,9 +166,9 @@ automatisch übermittelt.
|
|||
.SS [output]
|
||||
.TP
|
||||
\fBdebug=\fP\fISTRING\fP[\fB,\fP\fISTRING\fP...]
|
||||
Gebe Testmeldungen aus für den angegebenen Logger. Verfügbare Logger sind
|
||||
\fBcmdline\fP, \fBchecking\fP,\fBcache\fP, \fBgui\fP, \fBdns\fP, \fBthread\fP und \fBall\fP. Die
|
||||
Angabe \fBall\fP ist ein Synonym für alle verfügbaren Logger.
|
||||
Print debugging output for the given modules. Available debug modules are
|
||||
\fBcmdline\fP, \fBchecking\fP, \fBcache\fP, \fBdns\fP, \fBthread\fP, \fBplugins\fP and
|
||||
\fBall\fP. Specifying \fBall\fP is an alias for specifying all available loggers.
|
||||
.br
|
||||
[output]
|
||||
.TP
|
||||
|
|
@ -277,7 +276,7 @@ Setze Warnfarbe. Standard ist \fBbold;yellow\fP.
|
|||
Setze Downloadzeitfarbe. Standard ist \fBdefault\fP.
|
||||
.TP
|
||||
\fBcolorreset=\fP\fISTRING\fP
|
||||
Setze Reset Farbe. Standard ist \fBdefault\fP.
|
||||
Set reset color. Default is \fBdefault\fP.
|
||||
.SS [gml]
|
||||
.TP
|
||||
\fBfilename=\fP\fISTRING\fP
|
||||
|
|
@ -329,7 +328,7 @@ Siehe [text] Sektion weiter oben.
|
|||
Setze Datenbankname zum Speichern. Standard ist \fBlinksdb\fP.
|
||||
.TP
|
||||
\fBseparator=\fP\fICHAR\fP
|
||||
Setze SQL Kommandotrennzeichen. Standard ist ein Strichpunkt (\fB;\fP).
|
||||
Set SQL command separator character. Default is a semicolon (\fB;\fP).
|
||||
.SS [html]
|
||||
.TP
|
||||
\fBfilename=\fP\fISTRING\fP
|
||||
|
|
@ -404,7 +403,7 @@ Eine Nummer zwischen 0.0 und 1.0, welche die Priorität festlegt. Die
|
|||
Standardpriorität für die erste URL ist 1.0, für alle Kind\-URLs ist sie 0.5.
|
||||
.TP
|
||||
\fBfrequency=\fP[\fBalways\fP|\fBhourly\fP|\fBdaily\fP|\fBweekly\fP|\fBmonthly\fP|\fByearly\fP|\fBnever\fP]
|
||||
Die Häufigkeit mit der Seiten sich ändern.
|
||||
How frequently pages are changing.
|
||||
.
|
||||
.SH "AUSGABE PARTS"
|
||||
\fBall\fP (für alle Teile)
|
||||
|
|
@ -458,9 +457,11 @@ GeoIP or pygeoip and a local country or city lookup DB installed.
|
|||
Define a regular expression which prints a warning if it matches any content
|
||||
of the checked link. This applies only to valid pages, so we can get their
|
||||
content.
|
||||
|
||||
.TP
|
||||
\fBwarningregex=\fP\fIREGEX\fP
|
||||
Use this to check for pages that contain some form of error message, for
|
||||
example 'This page has moved' or 'Oracle Application error'.
|
||||
example "This page has moved" or "Oracle Application error". \fIREGEX\fP should
|
||||
be unquoted.
|
||||
|
||||
Man beachte, dass mehrere Werte in dem regulären Ausdruck kombiniert
|
||||
werden können, zum Beispiel "(Diese Seite ist umgezogen|Oracle
|
||||
|
|
|
|||
|
|
@ -11,23 +11,9 @@ installation is recommended.
|
|||
|
||||
- Install Python >= 2.7.2 from http://www.python.org/
|
||||
|
||||
- Qt4 SDK development tools from http://qt.nokia.com/downloads
|
||||
The binary "qcollectiongenerator" is used to generate the
|
||||
documentation files.
|
||||
|
||||
- Install PyQt >= 4.8 from
|
||||
http://www.riverbankcomputing.co.uk/software/pyqt/download
|
||||
|
||||
- *Optional, for syntax highlighting in the GUI editor*, install
|
||||
QScintilla from
|
||||
http://www.riverbankcomputing.co.uk/software/qscintilla/download
|
||||
|
||||
- *On Windows only*, install the Windows SDK
|
||||
http://msdn.microsoft.com/de-de/windows/bb980924
|
||||
|
||||
- *On Windows only*, install InnoSetup from
|
||||
http://www.jrsoftware.org/isinfo.php
|
||||
|
||||
- *On Windows only*, download and install the Microsoft
|
||||
Visual C++ 2008 runtime from
|
||||
http://www.microsoft.com/downloads/details.aspx?FamilyID=9b2da534-3e03-4391-8a4d-074b9f2bc1bf&displaylang=en
|
||||
|
|
@ -43,7 +29,7 @@ installation is recommended.
|
|||
Setup for Unix/Linux
|
||||
--------------------
|
||||
Execute ``make localbuild`` to compile a local version and execute
|
||||
``./linkchecker`` or ``./linkchecker-gui``.
|
||||
``./linkchecker``.
|
||||
Execute ``make test`` to run the unittest suite.
|
||||
Execute ``make dist`` to build a distributable source package.
|
||||
|
||||
|
|
@ -51,7 +37,7 @@ Execute ``make dist`` to build a distributable source package.
|
|||
Setup for Mac OS X
|
||||
------------------
|
||||
Execute ``make localbuild`` to compile a local version and execute
|
||||
``./linkchecker`` or ``./linkchecker-gui``.
|
||||
``./linkchecker``.
|
||||
Execute ``make test`` to run the unittest suite.
|
||||
Execute ``make app`` to build a distributable source package.
|
||||
|
||||
|
|
|
|||
|
|
@ -11,7 +11,6 @@ branches:
|
|||
before_install:
|
||||
- brew update
|
||||
- brew install python
|
||||
- brew install pyqt
|
||||
- brew install gettext
|
||||
- brew link --force gettext
|
||||
# command to install dependencies
|
||||
|
|
|
|||
|
|
@ -1,23 +0,0 @@
|
|||
.TH LINKCHECKER-GUI 1 2009-01-10 "LinkChecker GUI" "LinkChecker GUI client"
|
||||
.SH NAME
|
||||
linkchecker-gui - GUI client to check links of websites and HTML documents
|
||||
.
|
||||
.SH SYNOPSIS
|
||||
\fBlinkchecker-gui\fP [\fIfile-or-url-or-project\fP]
|
||||
.
|
||||
.SH DESCRIPTION
|
||||
A graphical interface to check links of websites and HTML documents.
|
||||
.
|
||||
.SH PROJECT FILES
|
||||
A project file has a .lcp extension. The file stores all active preferences
|
||||
and the current checked URL. Project files can be loaded with the
|
||||
menu entry or with drag-and-drop on the GUI window.
|
||||
|
||||
.SH "SEE ALSO"
|
||||
\fBlinkchecker\fP(1)
|
||||
.
|
||||
.SH AUTHOR
|
||||
Bastian Kleineidam <bastian.kleineidam@web.de>
|
||||
.
|
||||
.SH COPYRIGHT
|
||||
Copyright \(co 2009-2014 Bastian Kleineidam
|
||||
|
|
@ -31,7 +31,7 @@ HTML and CSS syntax check
|
|||
.IP \(bu
|
||||
Antivirus check
|
||||
.IP \(bu
|
||||
a command line, GUI and web interface
|
||||
a command line and web interface
|
||||
.SH EXAMPLES
|
||||
The most common use checks the given domain recursively:
|
||||
\fBlinkchecker http://www.example.com/\fP
|
||||
|
|
@ -85,7 +85,7 @@ Print available check plugins and exit.
|
|||
\fB\-D\fP\fISTRING\fP, \fB\-\-debug=\fP\fISTRING\fP
|
||||
Print debugging output for the given logger.
|
||||
Available loggers are \fBcmdline\fP, \fBchecking\fP,
|
||||
\fBcache\fP, \fBgui\fP, \fBdns\fP and \fBall\fP.
|
||||
\fBcache\fP, \fBdns\fP, \fBplugins\fP and \fBall\fP.
|
||||
Specifying \fBall\fP is an alias for specifying all available loggers.
|
||||
The option can be given multiple times to debug with more
|
||||
than one logger.
|
||||
|
|
|
|||
|
|
@ -77,8 +77,7 @@ Command line option: none
|
|||
.TP
|
||||
\fBmaxrunseconds=\fP\fINUMBER\fP
|
||||
Stop checking new URLs after the given number of seconds. Same as if the
|
||||
user stops (by hitting Ctrl-C or clicking the abort button in the GUI)
|
||||
after the given number of seconds.
|
||||
user stops (by hitting Ctrl-C) after the given number of seconds.
|
||||
.br
|
||||
The default is not to stop until all URLs are checked.
|
||||
.br
|
||||
|
|
@ -161,9 +160,9 @@ values are submitted automatically.
|
|||
.SS \fB[output]\fP
|
||||
.TP
|
||||
\fBdebug=\fP\fISTRING\fP[\fB,\fP\fISTRING\fP...]
|
||||
Print debugging output for the given loggers.
|
||||
Available loggers are \fBcmdline\fP, \fBchecking\fP,
|
||||
\fBcache\fP, \fBgui\fP, \fBdns\fP, \fBthread\fP and \fBall\fP.
|
||||
Print debugging output for the given modules.
|
||||
Available debug modules are \fBcmdline\fP, \fBchecking\fP,
|
||||
\fBcache\fP, \fBdns\fP, \fBthread\fP, \fBplugins\fP and \fBall\fP.
|
||||
Specifying \fBall\fP is an alias for specifying all available loggers.
|
||||
.br
|
||||
Command line option: \fB\-\-debug\fP
|
||||
|
|
|
|||
99
doc/fr.po
|
|
@ -1227,102 +1227,3 @@ msgstr ""
|
|||
msgid "Copyright \\(co 2000-2009 Bastian Kleineidam"
|
||||
msgstr ""
|
||||
|
||||
# type: TH
|
||||
#~ msgid "10 March 2001"
|
||||
#~ msgstr "10 mars 2001"
|
||||
|
||||
# type: Plain text
|
||||
#, fuzzy
|
||||
#~ msgid "Note that by default only errors and warnings are logged."
|
||||
#~ msgstr "Notez que seules les erreurs sont journalisées par défaut."
|
||||
|
||||
# type: TP
|
||||
#~ msgid "B<-f>I<configfile>, B<--config=>I<configfile>"
|
||||
#~ msgstr "B<-f>I<configfile>, B<--config=>I<configfile>"
|
||||
|
||||
# type: Plain text
|
||||
#~ msgid "Log warnings."
|
||||
#~ msgstr "Journaliser les avertissements."
|
||||
|
||||
# type: SS
|
||||
#~ msgid "Deprecated options"
|
||||
#~ msgstr "Options obsolètes"
|
||||
|
||||
# type: Plain text
|
||||
#~ msgid ""
|
||||
#~ "Print check status every 5 seconds to stderr. This is the default now."
|
||||
#~ msgstr ""
|
||||
#~ "Afficher l'état des vérifications toutes les 5 secondes sur la sortie "
|
||||
#~ "d'erreur. C'est le comportement par défaut."
|
||||
|
||||
# type: Plain text
|
||||
#~ msgid ""
|
||||
#~ "A B<!> before any regex negates it. So B<!^mailto:> matches everything "
|
||||
#~ "but a mailto link."
|
||||
#~ msgstr ""
|
||||
#~ "Un B<!> avant une expression rationnelle l'inverse. Ainsi B<!^mailto:> "
|
||||
#~ "correspond à tout sauf un lien mailto."
|
||||
|
||||
# type: TP
|
||||
#~ msgid "B<-i>I<regex>, B<--intern=>I<regex>"
|
||||
#~ msgstr "B<-i>I<regex>, B<--intern=>I<regex>"
|
||||
|
||||
# type: Plain text
|
||||
#~ msgid ""
|
||||
#~ "Assume URLs that match the given regular expression as internal. "
|
||||
#~ "LinkChecker descends recursively only to internal URLs, not to external."
|
||||
#~ msgstr ""
|
||||
#~ "Supposer que les URL correspondant à l'expression rationnelle donnée sont "
|
||||
#~ "internes. LinkChecker ne descend récursivement que sur les URL internes, "
|
||||
#~ "et pas sur les externes."
|
||||
|
||||
# type: TP
|
||||
#~ msgid "B<-e>I<regex>, B<--extern=>I<regex>"
|
||||
#~ msgstr "B<-e>I<regex>, B<--extern=>I<regex>"
|
||||
|
||||
# type: Plain text
|
||||
#~ msgid ""
|
||||
#~ "Assume urls that match the given regular expression as external. Only "
|
||||
#~ "internal HTML links are checked recursively."
|
||||
#~ msgstr ""
|
||||
#~ "Supposer que les URL correspondant à l'expression donnée sont externes. "
|
||||
#~ "Seuls les liens HTML internes sont vérifiés récursivement."
|
||||
|
||||
# type: TP
|
||||
#~ msgid "B<--extern-strict=>I<regex>"
|
||||
#~ msgstr "B<--extern-strict=>I<regex>"
|
||||
|
||||
# type: Plain text
|
||||
#~ msgid ""
|
||||
#~ "Assume urls that match the given regular expression as strict external. "
|
||||
#~ "Only internal HTML links are checked recursively."
|
||||
#~ msgstr ""
|
||||
#~ "Supposer que les URL correspondant à l'expression donnée sont strictement "
|
||||
#~ "externes. Seuls les liens HTML internes sont vérifiés récursivement."
|
||||
|
||||
# type: TP
|
||||
#~ msgid "B<-s>, B<--extern-strict-all>"
|
||||
#~ msgstr "B<-s>, B<--extern-strict-all>"
|
||||
|
||||
# type: Plain text
|
||||
#~ msgid ""
|
||||
#~ "Check only the syntax of external links, do not try to connect to them. "
|
||||
#~ "For local file urls, only local files are internal. For http and ftp "
|
||||
#~ "urls, all urls at the same domain name are internal."
|
||||
#~ msgstr ""
|
||||
#~ "Ne vérifier que la syntaxe des liens externes, sans que l'on essaie de "
|
||||
#~ "s'y connecter. Pour les URL locales, seuls les fichiers locaux sont "
|
||||
#~ "internes. Pour les URL HTTP et FTP, toutes les URL avec le même nom de "
|
||||
#~ "domaine sont internes."
|
||||
|
||||
# type: TP
|
||||
#~ msgid "B<-d>, B<--denyallow>"
|
||||
#~ msgstr "B<-d>, B<--denyallow>"
|
||||
|
||||
# type: Plain text
|
||||
#~ msgid ""
|
||||
#~ "Swap checking order to external/internal. Default checking order is "
|
||||
#~ "internal/external."
|
||||
#~ msgstr ""
|
||||
#~ "Inverser l'ordre de vérification en externe/interne. L'ordre de "
|
||||
#~ "vérification par défaut est interne/externe."
|
||||
|
|
|
|||
|
|
@ -1,30 +0,0 @@
|
|||
HELPFILES := lccollection.qhc
|
||||
HTMLFILES := index.html
|
||||
OXYGEN := ${HOME}/src/oxygen-gitsvn
|
||||
ICOICONS := logo16x16.png logo32x32.png
|
||||
ICNSICONS := logo16x16.png logo32x32.png logo48x48.png logo128x128.png
|
||||
|
||||
all: $(HELPFILES) $(HTMLFILES)
|
||||
|
||||
clean:
|
||||
-rm -f *.qhc *.qch
|
||||
|
||||
%.html: %.txt html.header html.footer
|
||||
(cat html.header; markdown2 $<; cat html.footer) > $@
|
||||
|
||||
test:
|
||||
xmllint --valid --noout $(HTMLFILES)
|
||||
|
||||
%.qhc: %.qhcp lcdoc.qhp $(HTMLFILES)
|
||||
-qcollectiongenerator $< -o $@
|
||||
|
||||
logo%.png: $(OXYGEN)/%/categories/applications-development-web.png
|
||||
cp $< $@
|
||||
|
||||
favicon.ico: $(ICOICONS)
|
||||
png2ico favicon.ico $(ICOICONS)
|
||||
|
||||
favicon.icns: $(ICNSICONS)
|
||||
png2icns favicon.icns $(ICNSICONS)
|
||||
|
||||
.PHONY: clean test
|
||||
|
Before Width: | Height: | Size: 3.6 KiB |
|
|
@ -1,6 +0,0 @@
|
|||
<hr/>
|
||||
<div class="footer">
|
||||
© Copyright 2012-2014, Bastian Kleineidam.
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -1,24 +0,0 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
|
||||
<title>Check websites for broken links</title>
|
||||
<link rel="stylesheet" href="sphinxdoc.css" type="text/css" />
|
||||
<link rel="stylesheet" href="pygments.css" type="text/css" />
|
||||
<style type="text/css">
|
||||
img { border: 0; }
|
||||
</style>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<div style="background-color: white; text-align: left; padding: 10px 10px 15px 15px">
|
||||
<table border="0"><tr>
|
||||
<td><img
|
||||
src="logo64x64.png" border="0" alt="LinkChecker"/></td>
|
||||
<td><h1>LinkChecker</h1></td>
|
||||
</tr></table>
|
||||
</div>
|
||||
|
||||
|
|
@ -1,204 +0,0 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
|
||||
<title>Check websites for broken links</title>
|
||||
<link rel="stylesheet" href="sphinxdoc.css" type="text/css" />
|
||||
<link rel="stylesheet" href="pygments.css" type="text/css" />
|
||||
<style type="text/css">
|
||||
img { border: 0; }
|
||||
</style>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<div style="background-color: white; text-align: left; padding: 10px 10px 15px 15px">
|
||||
<table border="0"><tr>
|
||||
<td><img
|
||||
src="logo64x64.png" border="0" alt="LinkChecker"/></td>
|
||||
<td><h1>LinkChecker</h1></td>
|
||||
</tr></table>
|
||||
</div>
|
||||
|
||||
<h1>Documentation</h1>
|
||||
|
||||
<h2>Basic usage</h2>
|
||||
|
||||
<p>To check a URL like <a href="http://www.example.org/">http://www.example.org/</a>
|
||||
it is enough to
|
||||
type <code>linkchecker www.example.org</code> on the command line or
|
||||
type <code>www.example.org</code> in the GUI application. This will check the
|
||||
complete domain of <code>http://www.example.org</code> recursively. All links
|
||||
pointing outside of the domain are also checked for validity.</p>
|
||||
|
||||
<p>Local files can also be checked. On Unix or OSX systems the syntax
|
||||
is <code>file:///path/to/my/file.html</code>. On Windows the syntax is
|
||||
<code>file://C|/path/to/my/file.html</code>. When directories are checked,
|
||||
all included files will be checked.</p>
|
||||
|
||||
<p>On the GUI client the <code>Edit</code> menu has shortcuts for bookmark
|
||||
files. For example if Google Chrome is installed, there will be
|
||||
a menu entry called <code>Insert Google Chrome bookmark file</code> which
|
||||
can be used to check all browser bookmarks.</p>
|
||||
|
||||
<h2>Options</h2>
|
||||
|
||||
<p>The commandline client options are documented
|
||||
in the <a href="http://wummel.github.io/linkchecker/man1/linkchecker.1.html">linkchecker(1) manual page</a>.</p>
|
||||
|
||||
<p>In the GUI client, the following options are available:</p>
|
||||
|
||||
<ul>
|
||||
<li><p>Recursive depth</p>
|
||||
|
||||
<p>Check recursively all links up to given depth.
|
||||
A negative depth (eg. <code>-1</code>) will enable infinite recursion.</p></li>
|
||||
<li><p>Verbose output</p>
|
||||
|
||||
<p>If set, log all checked URLs. Default is to log only errors and warnings.</p></li>
|
||||
<li><p>Debug</p>
|
||||
|
||||
<p>Prints debugging output in a separate window which can be seen with
|
||||
<code>Help -> Show debug</code>.</p></li>
|
||||
<li><p>Debug memory usage</p>
|
||||
|
||||
<p>Profiles memory usage and writes statistics and a dump file when checking
|
||||
stops. The dump file can be examined with
|
||||
<a href="https://github.com/wummel/linkchecker/blob/master/tests/analyze_memdump.py">external tools</a>.
|
||||
This option should only be useful for developers.</p></li>
|
||||
<li><p>Warning strings</p>
|
||||
|
||||
<p>Log a warning if any strings are found in the content of the checked
|
||||
URL. Strings are entered one per line.</p>
|
||||
|
||||
<p>Use this to check for pages that contain some form of error, for example
|
||||
"<code>This page has moved</code>" or "<code>Oracle Application error</code>".</p></li>
|
||||
<li><p>Ignoring URLs</p>
|
||||
|
||||
<p>URLs matching the given regular expressions will be ignored and not checked.
|
||||
Useful if certain URL types should not be checked like emails (ie.
|
||||
"<code>^mailto:</code>").</p></li>
|
||||
</ul>
|
||||
|
||||
<h2>Configuration file</h2>
|
||||
|
||||
<p>Each user can edit a configuration with advanced options for
|
||||
checking or filtering. The
|
||||
<a href="http://wummel.github.io/linkchecker/man5/linkcheckerrc.5.html">linkcheckerrc(5) manual page</a>
|
||||
documents all the options.</p>
|
||||
|
||||
<p>In the GUI client the configuration file can be edited directly from
|
||||
the dialog <code>Edit -> Options</code> and the clicking on <code>Edit</code>.</p>
|
||||
|
||||
<h2>Performed checks</h2>
|
||||
|
||||
<p>All URLs have to pass a preliminary syntax test.
|
||||
After the syntax check passes, the URL is queued for connection
|
||||
checking. All connection check types are described below.</p>
|
||||
|
||||
<ul>
|
||||
<li><p>HTTP links (<code>http:</code>, <code>https:</code>)</p>
|
||||
|
||||
<p>After connecting to the given HTTP server the given path
|
||||
or query is requested. All redirections are followed, and
|
||||
if user/password is given it will be used as authorization
|
||||
when necessary.
|
||||
Permanently moved pages (status code 301) issue a warning.
|
||||
All final HTTP status codes other than 2xx are errors.</p>
|
||||
|
||||
<p>For HTTPS links, the SSL certificate is checked against the
|
||||
given hostname. If it does not match, a warnings is printed.</p></li>
|
||||
<li><p>Local files (<code>file:</code>)</p>
|
||||
|
||||
<p>A regular, readable file that can be opened is valid. A readable
|
||||
directory is also valid. All other files, for example unreadable,
|
||||
non-existing or device files are errors.</p>
|
||||
|
||||
<p>File contents are checked for recursion. If they are parseable
|
||||
files (for example HTML files), all links in that file will be
|
||||
checked.</p></li>
|
||||
<li><p>Mail links (<code>mailto:</code>)</p>
|
||||
|
||||
<p>A mailto: link resolves to a list of email addresses.
|
||||
If one email address fails the whole list will fail.
|
||||
For each email address the following things are checked:</p>
|
||||
|
||||
<ol>
|
||||
<li>Check the address syntax, both the part before and after
|
||||
the @ sign.</li>
|
||||
<li>Look up the MX DNS records. If no MX record is found,
|
||||
print an error.</li>
|
||||
<li>Check if one of the MX mail hosts accept an SMTP connection.
|
||||
Check hosts with higher priority first.
|
||||
If none of the hosts accept SMTP, a warning is printed.</li>
|
||||
<li>Try to verify the address with the VRFY command. If there is
|
||||
an answer, the verified address is printed as an info.</li>
|
||||
</ol></li>
|
||||
<li><p>FTP links (<code>ftp:</code>)</p>
|
||||
|
||||
<p>For FTP links the following is checked:</p>
|
||||
|
||||
<ol>
|
||||
<li>Connect to the specified host.</li>
|
||||
<li>Try to login with the given user and password. The default
|
||||
user is <code>anonymous</code>, the default password is <code>anonymous@</code>.</li>
|
||||
<li>Try to change to the given directory.</li>
|
||||
<li>List the file with the NLST command.</li>
|
||||
</ol></li>
|
||||
<li><p>Telnet links (<code>telnet:</code>)</p>
|
||||
|
||||
<p>A connect and if user/password are given, login to the
|
||||
given telnet server is tried.</p></li>
|
||||
<li><p>NNTP links (<code>news:</code>, <code>snews:</code>, <code>nntp</code>)</p>
|
||||
|
||||
<p>A connect is tried to connect to the given NNTP server. If a news group or
|
||||
article is specified, it will be requested from the server.</p></li>
|
||||
<li><p>Unsupported links (<code>javascript:</code>, etc.)</p>
|
||||
|
||||
<p>An unsupported link will print a warning, but no error. No further checking
|
||||
will be made.</p>
|
||||
|
||||
<p>The complete list of recognized, but unsupported links can be seen in the
|
||||
<a href="https://github.com/wummel/linkchecker/blob/master/linkcheck/checker/unknownurl.py">unknownurl.py</a>
|
||||
source file. The most prominent of them are JavaScript links.</p></li>
|
||||
</ul>
|
||||
|
||||
<h2>Recursion</h2>
|
||||
|
||||
<p>Before descending recursively into a URL, it has to fulfill several
|
||||
conditions. The conditions are checked in this order:</p>
|
||||
|
||||
<ol>
|
||||
<li>The URL must be valid.</li>
|
||||
<li>The URL must be parseable. This currently includes HTML files,
|
||||
Bookmarks files (Opera, Chrome or Safari), directories and on
|
||||
Windows systems MS Word files if Word and the Pywin32 module
|
||||
is installed on your system.
|
||||
If a file type cannot be determined (for example it does not have
|
||||
a common HTML file extension, and the content does not look like
|
||||
HTML), it is assumed to be non-parseable.</li>
|
||||
<li>The URL content must be retrievable. This is usually the case
|
||||
except for example mailto: or unknown URL types.</li>
|
||||
<li>The maximum recursion level must not be exceeded. It is configured
|
||||
with the <code>--recursion-level</code> command line option, the recursion
|
||||
level GUI option, or through the configuration file.
|
||||
The recursion level is unlimited by default.</li>
|
||||
<li>It must not match the ignored URL list. This is controlled with
|
||||
the <code>--ignore-url</code> command line option or through the
|
||||
configuration file.</li>
|
||||
<li>The Robots Exclusion Protocol must allow links in the URL to be
|
||||
followed recursively. This is checked by evaluating the servers
|
||||
robots.txt file and searching for a "nofollow" directive in the
|
||||
HTML header data.</li>
|
||||
</ol>
|
||||
|
||||
<p>Note that the local and FTP directory recursion reads all files in that
|
||||
directory, not just a subset like <code>index.htm*</code>.</p>
|
||||
<hr/>
|
||||
<div class="footer">
|
||||
© Copyright 2012-2014, Bastian Kleineidam.
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -1,175 +0,0 @@
|
|||
# Documentation
|
||||
|
||||
## Basic usage
|
||||
|
||||
To check a URL like [http://www.example.org/](http://www.example.org/)
|
||||
it is enough to
|
||||
type ``linkchecker www.example.org`` on the command line or
|
||||
type ``www.example.org`` in the GUI application. This will check the
|
||||
complete domain of ``http://www.example.org`` recursively. All links
|
||||
pointing outside of the domain are also checked for validity.
|
||||
|
||||
Local files can also be checked. On Unix or OSX systems the syntax
|
||||
is ``file:///path/to/my/file.html``. On Windows the syntax is
|
||||
``file://C|/path/to/my/file.html``. When directories are checked,
|
||||
all included files will be checked.
|
||||
|
||||
On the GUI client the ``Edit`` menu has shortcuts for bookmark
|
||||
files. For example if Google Chrome is installed, there will be
|
||||
a menu entry called ``Insert Google Chrome bookmark file`` which
|
||||
can be used to check all browser bookmarks.
|
||||
|
||||
## Options
|
||||
|
||||
The commandline client options are documented
|
||||
in the [linkchecker(1) manual page](http://wummel.github.io/linkchecker/man1/linkchecker.1.html).
|
||||
|
||||
In the GUI client, the following options are available:
|
||||
|
||||
- Recursive depth
|
||||
|
||||
Check recursively all links up to given depth.
|
||||
A negative depth (eg. ``-1``) will enable infinite recursion.
|
||||
|
||||
- Verbose output
|
||||
|
||||
If set, log all checked URLs. Default is to log only errors and warnings.
|
||||
|
||||
- Debug
|
||||
|
||||
Prints debugging output in a separate window which can be seen with
|
||||
``Help -> Show debug``.
|
||||
|
||||
- Debug memory usage
|
||||
|
||||
Profiles memory usage and writes statistics and a dump file when checking
|
||||
stops. The dump file can be examined with
|
||||
[external tools](https://github.com/wummel/linkchecker/blob/master/tests/analyze_memdump.py).
|
||||
This option should only be useful for developers.
|
||||
|
||||
- Warning strings
|
||||
|
||||
Log a warning if any strings are found in the content of the checked
|
||||
URL. Strings are entered one per line.
|
||||
|
||||
Use this to check for pages that contain some form of error, for example
|
||||
"``This page has moved``" or "``Oracle Application error``".
|
||||
|
||||
- Ignoring URLs
|
||||
|
||||
URLs matching the given regular expressions will be ignored and not checked.
|
||||
Useful if certain URL types should not be checked like emails (ie.
|
||||
"``^mailto:``").
|
||||
|
||||
## Configuration file
|
||||
|
||||
Each user can edit a configuration with advanced options for
|
||||
checking or filtering. The
|
||||
[linkcheckerrc(5) manual page](http://wummel.github.io/linkchecker/man5/linkcheckerrc.5.html)
|
||||
documents all the options.
|
||||
|
||||
In the GUI client the configuration file can be edited directly from
|
||||
the dialog ``Edit -> Options`` and the clicking on ``Edit``.
|
||||
|
||||
## Performed checks
|
||||
|
||||
All URLs have to pass a preliminary syntax test.
|
||||
After the syntax check passes, the URL is queued for connection
|
||||
checking. All connection check types are described below.
|
||||
|
||||
- HTTP links (``http:``, ``https:``)
|
||||
|
||||
After connecting to the given HTTP server the given path
|
||||
or query is requested. All redirections are followed, and
|
||||
if user/password is given it will be used as authorization
|
||||
when necessary.
|
||||
Permanently moved pages (status code 301) issue a warning.
|
||||
All final HTTP status codes other than 2xx are errors.
|
||||
|
||||
For HTTPS links, the SSL certificate is checked against the
|
||||
given hostname. If it does not match, a warnings is printed.
|
||||
|
||||
- Local files (``file:``)
|
||||
|
||||
A regular, readable file that can be opened is valid. A readable
|
||||
directory is also valid. All other files, for example unreadable,
|
||||
non-existing or device files are errors.
|
||||
|
||||
File contents are checked for recursion. If they are parseable
|
||||
files (for example HTML files), all links in that file will be
|
||||
checked.
|
||||
|
||||
- Mail links (``mailto:``)
|
||||
|
||||
A mailto: link resolves to a list of email addresses.
|
||||
If one email address fails the whole list will fail.
|
||||
For each email address the following things are checked:
|
||||
|
||||
1. Check the address syntax, both the part before and after
|
||||
the @ sign.
|
||||
2. Look up the MX DNS records. If no MX record is found,
|
||||
print an error.
|
||||
3. Check if one of the MX mail hosts accept an SMTP connection.
|
||||
Check hosts with higher priority first.
|
||||
If none of the hosts accept SMTP, a warning is printed.
|
||||
4. Try to verify the address with the VRFY command. If there is
|
||||
an answer, the verified address is printed as an info.
|
||||
|
||||
- FTP links (``ftp:``)
|
||||
|
||||
For FTP links the following is checked:
|
||||
|
||||
1. Connect to the specified host.
|
||||
2. Try to login with the given user and password. The default
|
||||
user is ``anonymous``, the default password is ``anonymous@``.
|
||||
3. Try to change to the given directory.
|
||||
4. List the file with the NLST command.
|
||||
|
||||
- Telnet links (``telnet:``)
|
||||
|
||||
A connect and if user/password are given, login to the
|
||||
given telnet server is tried.
|
||||
|
||||
- NNTP links (``news:``, ``snews:``, ``nntp``)
|
||||
|
||||
A connect is tried to connect to the given NNTP server. If a news group or
|
||||
article is specified, it will be requested from the server.
|
||||
|
||||
- Unsupported links (``javascript:``, etc.)
|
||||
|
||||
An unsupported link will print a warning, but no error. No further checking
|
||||
will be made.
|
||||
|
||||
The complete list of recognized, but unsupported links can be seen in the
|
||||
[unknownurl.py](https://github.com/wummel/linkchecker/blob/master/linkcheck/checker/unknownurl.py)
|
||||
source file. The most prominent of them are JavaScript links.
|
||||
|
||||
## Recursion
|
||||
|
||||
Before descending recursively into a URL, it has to fulfill several
|
||||
conditions. The conditions are checked in this order:
|
||||
|
||||
1. The URL must be valid.
|
||||
2. The URL must be parseable. This currently includes HTML files,
|
||||
Bookmarks files (Opera, Chrome or Safari), directories and on
|
||||
Windows systems MS Word files if Word and the Pywin32 module
|
||||
is installed on your system.
|
||||
If a file type cannot be determined (for example it does not have
|
||||
a common HTML file extension, and the content does not look like
|
||||
HTML), it is assumed to be non-parseable.
|
||||
3. The URL content must be retrievable. This is usually the case
|
||||
except for example mailto: or unknown URL types.
|
||||
4. The maximum recursion level must not be exceeded. It is configured
|
||||
with the ``--recursion-level`` command line option, the recursion
|
||||
level GUI option, or through the configuration file.
|
||||
The recursion level is unlimited by default.
|
||||
5. It must not match the ignored URL list. This is controlled with
|
||||
the ``--ignore-url`` command line option or through the
|
||||
configuration file.
|
||||
6. The Robots Exclusion Protocol must allow links in the URL to be
|
||||
followed recursively. This is checked by evaluating the servers
|
||||
robots.txt file and searching for a "nofollow" directive in the
|
||||
HTML header data.
|
||||
|
||||
Note that the local and FTP directory recursion reads all files in that
|
||||
directory, not just a subset like ``index.htm*``.
|
||||
|
|
@ -1,23 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<QHelpCollectionProject version="1.0">
|
||||
<assistant>
|
||||
<title>LinkChecker</title>
|
||||
<applicationIcon>logo16x16.png</applicationIcon>
|
||||
<cacheDirectory>bfk/LinkChecker</cacheDirectory>
|
||||
<startPage>qthelp://bfk.app.linkchecker/doc/index.html</startPage>
|
||||
<enableDocumentationManager>false</enableDocumentationManager>
|
||||
<enableAddressBar>false</enableAddressBar>
|
||||
<enableFilterFunctionality>false</enableFilterFunctionality>
|
||||
</assistant>
|
||||
<docFiles>
|
||||
<generate>
|
||||
<file>
|
||||
<input>lcdoc.qhp</input>
|
||||
<output>lcdoc.qch</output>
|
||||
</file>
|
||||
</generate>
|
||||
<register>
|
||||
<file>lcdoc.qch</file>
|
||||
</register>
|
||||
</docFiles>
|
||||
</QHelpCollectionProject>
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<QtHelpProject version="1.0">
|
||||
<namespace>bfk.app.linkchecker</namespace>
|
||||
<virtualFolder>doc</virtualFolder>
|
||||
<filterSection>
|
||||
<toc>
|
||||
<section title="LinkChecker documentation" ref="index.html"/>
|
||||
</toc>
|
||||
<files>
|
||||
<file>index.html</file>
|
||||
</files>
|
||||
</filterSection>
|
||||
</QtHelpProject>
|
||||
|
Before Width: | Height: | Size: 26 KiB |
|
Before Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 3.2 KiB |
|
Before Width: | Height: | Size: 6.1 KiB |
|
Before Width: | Height: | Size: 9.5 KiB |
|
|
@ -1,61 +0,0 @@
|
|||
.hll { background-color: #ffffcc }
|
||||
.c { color: #408090; font-style: italic } /* Comment */
|
||||
.err { border: 1px solid #FF0000 } /* Error */
|
||||
.k { color: #007020; font-weight: bold } /* Keyword */
|
||||
.o { color: #666666 } /* Operator */
|
||||
.cm { color: #408090; font-style: italic } /* Comment.Multiline */
|
||||
.cp { color: #007020 } /* Comment.Preproc */
|
||||
.c1 { color: #408090; font-style: italic } /* Comment.Single */
|
||||
.cs { color: #408090; background-color: #fff0f0 } /* Comment.Special */
|
||||
.gd { color: #A00000 } /* Generic.Deleted */
|
||||
.ge { font-style: italic } /* Generic.Emph */
|
||||
.gr { color: #FF0000 } /* Generic.Error */
|
||||
.gh { color: #000080; font-weight: bold } /* Generic.Heading */
|
||||
.gi { color: #00A000 } /* Generic.Inserted */
|
||||
.go { color: #303030 } /* Generic.Output */
|
||||
.gp { color: #c65d09; font-weight: bold } /* Generic.Prompt */
|
||||
.gs { font-weight: bold } /* Generic.Strong */
|
||||
.gu { color: #800080; font-weight: bold } /* Generic.Subheading */
|
||||
.gt { color: #0040D0 } /* Generic.Traceback */
|
||||
.kc { color: #007020; font-weight: bold } /* Keyword.Constant */
|
||||
.kd { color: #007020; font-weight: bold } /* Keyword.Declaration */
|
||||
.kn { color: #007020; font-weight: bold } /* Keyword.Namespace */
|
||||
.kp { color: #007020 } /* Keyword.Pseudo */
|
||||
.kr { color: #007020; font-weight: bold } /* Keyword.Reserved */
|
||||
.kt { color: #902000 } /* Keyword.Type */
|
||||
.m { color: #208050 } /* Literal.Number */
|
||||
.s { color: #4070a0 } /* Literal.String */
|
||||
.na { color: #4070a0 } /* Name.Attribute */
|
||||
.nb { color: #007020 } /* Name.Builtin */
|
||||
.nc { color: #0e84b5; font-weight: bold } /* Name.Class */
|
||||
.no { color: #60add5 } /* Name.Constant */
|
||||
.nd { color: #555555; font-weight: bold } /* Name.Decorator */
|
||||
.ni { color: #d55537; font-weight: bold } /* Name.Entity */
|
||||
.ne { color: #007020 } /* Name.Exception */
|
||||
.nf { color: #06287e } /* Name.Function */
|
||||
.nl { color: #002070; font-weight: bold } /* Name.Label */
|
||||
.nn { color: #0e84b5; font-weight: bold } /* Name.Namespace */
|
||||
.nt { color: #062873; font-weight: bold } /* Name.Tag */
|
||||
.nv { color: #bb60d5 } /* Name.Variable */
|
||||
.ow { color: #007020; font-weight: bold } /* Operator.Word */
|
||||
.w { color: #bbbbbb } /* Text.Whitespace */
|
||||
.mf { color: #208050 } /* Literal.Number.Float */
|
||||
.mh { color: #208050 } /* Literal.Number.Hex */
|
||||
.mi { color: #208050 } /* Literal.Number.Integer */
|
||||
.mo { color: #208050 } /* Literal.Number.Oct */
|
||||
.sb { color: #4070a0 } /* Literal.String.Backtick */
|
||||
.sc { color: #4070a0 } /* Literal.String.Char */
|
||||
.sd { color: #4070a0; font-style: italic } /* Literal.String.Doc */
|
||||
.s2 { color: #4070a0 } /* Literal.String.Double */
|
||||
.se { color: #4070a0; font-weight: bold } /* Literal.String.Escape */
|
||||
.sh { color: #4070a0 } /* Literal.String.Heredoc */
|
||||
.si { color: #70a0d0; font-style: italic } /* Literal.String.Interpol */
|
||||
.sx { color: #c65d09 } /* Literal.String.Other */
|
||||
.sr { color: #235388 } /* Literal.String.Regex */
|
||||
.s1 { color: #4070a0 } /* Literal.String.Single */
|
||||
.ss { color: #517918 } /* Literal.String.Symbol */
|
||||
.bp { color: #007020 } /* Name.Builtin.Pseudo */
|
||||
.vc { color: #bb60d5 } /* Name.Variable.Class */
|
||||
.vg { color: #bb60d5 } /* Name.Variable.Global */
|
||||
.vi { color: #bb60d5 } /* Name.Variable.Instance */
|
||||
.il { color: #208050 } /* Literal.Number.Integer.Long */
|
||||
|
|
@ -1,303 +0,0 @@
|
|||
/**
|
||||
* Sphinx stylesheet -- sphinxdoc theme
|
||||
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
*
|
||||
* Originally created by Armin Ronacher for Werkzeug, adapted by Georg Brandl.
|
||||
*/
|
||||
|
||||
@import url("basic.css");
|
||||
|
||||
/* -- page layout ----------------------------------------------------------- */
|
||||
|
||||
body {
|
||||
font-family: 'Lucida Grande', 'Lucida Sans Unicode', 'Geneva',
|
||||
'Verdana', sans-serif;
|
||||
font-size: 14px;
|
||||
letter-spacing: -0.01em;
|
||||
line-height: 150%;
|
||||
text-align: center;
|
||||
background-color: #BFD1D4;
|
||||
color: black;
|
||||
padding: 0;
|
||||
border: 1px solid #aaa;
|
||||
|
||||
margin: 0px 80px 0px 80px;
|
||||
min-width: 740px;
|
||||
}
|
||||
|
||||
div.document {
|
||||
background-color: white;
|
||||
text-align: left;
|
||||
background-image: url(contents.png);
|
||||
background-repeat: repeat-x;
|
||||
}
|
||||
|
||||
div.bodywrapper {
|
||||
margin: 0 240px 0 0;
|
||||
border-right: 1px solid #ccc;
|
||||
}
|
||||
|
||||
div.body {
|
||||
margin: 0;
|
||||
padding: 0.5em 20px 20px 20px;
|
||||
}
|
||||
|
||||
div.related {
|
||||
font-size: 1em;
|
||||
}
|
||||
|
||||
div.related ul {
|
||||
background-image: url(navigation.png);
|
||||
height: 2em;
|
||||
border-top: 1px solid #ddd;
|
||||
border-bottom: 1px solid #ddd;
|
||||
}
|
||||
|
||||
div.related ul li {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
height: 2em;
|
||||
float: left;
|
||||
}
|
||||
|
||||
div.related ul li.right {
|
||||
float: right;
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
div.related ul li a {
|
||||
margin: 0;
|
||||
padding: 0 5px 0 5px;
|
||||
line-height: 1.75em;
|
||||
color: #EE9816;
|
||||
}
|
||||
|
||||
div.related ul li a:hover {
|
||||
color: #3CA8E7;
|
||||
}
|
||||
|
||||
div.sphinxsidebarwrapper {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
div.sphinxsidebar {
|
||||
margin: 0;
|
||||
padding: 0.5em 15px 15px 0;
|
||||
width: 210px;
|
||||
float: right;
|
||||
font-size: 1em;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
div.sphinxsidebar h3, div.sphinxsidebar h4 {
|
||||
margin: 1em 0 0.5em 0;
|
||||
font-size: 1em;
|
||||
padding: 0.1em 0 0.1em 0.5em;
|
||||
color: white;
|
||||
border: 1px solid #86989B;
|
||||
background-color: #AFC1C4;
|
||||
}
|
||||
|
||||
div.sphinxsidebar h3 a {
|
||||
color: white;
|
||||
}
|
||||
|
||||
div.sphinxsidebar ul {
|
||||
padding-left: 1.5em;
|
||||
margin-top: 7px;
|
||||
padding: 0;
|
||||
line-height: 130%;
|
||||
}
|
||||
|
||||
div.sphinxsidebar ul ul {
|
||||
margin-left: 20px;
|
||||
}
|
||||
|
||||
div.footer {
|
||||
background-color: #E3EFF1;
|
||||
color: #86989B;
|
||||
padding: 3px 8px 3px 0;
|
||||
clear: both;
|
||||
font-size: 0.8em;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
div.footer a {
|
||||
color: #86989B;
|
||||
}
|
||||
|
||||
/* -- body styles ----------------------------------------------------------- */
|
||||
|
||||
p {
|
||||
margin: 0.8em 0 0.5em 0;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #CA7900;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
color: #2491CF;
|
||||
}
|
||||
|
||||
h1 {
|
||||
margin: 0;
|
||||
padding: 0.7em 0 0.3em 0;
|
||||
font-size: 1.5em;
|
||||
color: #11557C;
|
||||
}
|
||||
|
||||
h2 {
|
||||
margin: 1.3em 0 0.2em 0;
|
||||
font-size: 1.35em;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
h3 {
|
||||
margin: 1em 0 -0.3em 0;
|
||||
font-size: 1.2em;
|
||||
}
|
||||
|
||||
div.body h1 a, div.body h2 a, div.body h3 a, div.body h4 a, div.body h5 a, div.body h6 a {
|
||||
color: black!important;
|
||||
}
|
||||
|
||||
h1 a.anchor, h2 a.anchor, h3 a.anchor, h4 a.anchor, h5 a.anchor, h6 a.anchor {
|
||||
display: none;
|
||||
margin: 0 0 0 0.3em;
|
||||
padding: 0 0.2em 0 0.2em;
|
||||
color: #aaa!important;
|
||||
}
|
||||
|
||||
h1:hover a.anchor, h2:hover a.anchor, h3:hover a.anchor, h4:hover a.anchor,
|
||||
h5:hover a.anchor, h6:hover a.anchor {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
h1 a.anchor:hover, h2 a.anchor:hover, h3 a.anchor:hover, h4 a.anchor:hover,
|
||||
h5 a.anchor:hover, h6 a.anchor:hover {
|
||||
color: #777;
|
||||
background-color: #eee;
|
||||
}
|
||||
|
||||
cite, code, tt {
|
||||
font-family: 'Consolas', 'Deja Vu Sans Mono',
|
||||
'Bitstream Vera Sans Mono', monospace;
|
||||
font-size: 0.95em;
|
||||
letter-spacing: 0.01em;
|
||||
}
|
||||
|
||||
tt {
|
||||
background-color: #f2f2f2;
|
||||
border-bottom: 1px solid #ddd;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
tt.descname, tt.descclassname, tt.xref {
|
||||
border: 0;
|
||||
}
|
||||
|
||||
hr {
|
||||
border: 1px solid #abc;
|
||||
margin: 2em;
|
||||
}
|
||||
|
||||
a tt {
|
||||
border: 0;
|
||||
color: #CA7900;
|
||||
}
|
||||
|
||||
a tt:hover {
|
||||
color: #2491CF;
|
||||
}
|
||||
|
||||
pre {
|
||||
font-family: 'Consolas', 'Deja Vu Sans Mono',
|
||||
'Bitstream Vera Sans Mono', monospace;
|
||||
font-size: 0.95em;
|
||||
letter-spacing: 0.015em;
|
||||
line-height: 120%;
|
||||
padding: 0.5em;
|
||||
border: 1px solid #ccc;
|
||||
background-color: #f8f8f8;
|
||||
}
|
||||
|
||||
pre a {
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
td.linenos pre {
|
||||
padding: 0.5em 0;
|
||||
}
|
||||
|
||||
div.quotebar {
|
||||
background-color: #f8f8f8;
|
||||
max-width: 250px;
|
||||
float: right;
|
||||
padding: 2px 7px;
|
||||
border: 1px solid #ccc;
|
||||
}
|
||||
|
||||
div.topic {
|
||||
background-color: #f8f8f8;
|
||||
}
|
||||
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
margin: 0 -0.5em 0 -0.5em;
|
||||
}
|
||||
|
||||
table td, table th {
|
||||
padding: 0.2em 0.5em 0.2em 0.5em;
|
||||
}
|
||||
|
||||
div.admonition, div.warning {
|
||||
font-size: 0.9em;
|
||||
margin: 1em 0 1em 0;
|
||||
border: 1px solid #86989B;
|
||||
background-color: #f7f7f7;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
div.admonition p, div.warning p {
|
||||
margin: 0.5em 1em 0.5em 1em;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
div.admonition pre, div.warning pre {
|
||||
margin: 0.4em 1em 0.4em 1em;
|
||||
}
|
||||
|
||||
div.admonition p.admonition-title,
|
||||
div.warning p.admonition-title {
|
||||
margin: 0;
|
||||
padding: 0.1em 0 0.1em 0.5em;
|
||||
color: white;
|
||||
border-bottom: 1px solid #86989B;
|
||||
font-weight: bold;
|
||||
background-color: #AFC1C4;
|
||||
}
|
||||
|
||||
div.warning {
|
||||
border: 1px solid #940000;
|
||||
}
|
||||
|
||||
div.warning p.admonition-title {
|
||||
background-color: #CF0000;
|
||||
border-bottom-color: #940000;
|
||||
}
|
||||
|
||||
div.admonition ul, div.admonition ol,
|
||||
div.warning ul, div.warning ol {
|
||||
margin: 0.1em 0.5em 0.5em 3em;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
div.versioninfo {
|
||||
margin: 1em 0 0 0;
|
||||
border: 1px solid #ccc;
|
||||
background-color: #DDEAF0;
|
||||
padding: 8px;
|
||||
line-height: 1.3em;
|
||||
font-size: 0.9em;
|
||||
}
|
||||
|
|
@ -55,39 +55,28 @@ First, install the required software.
|
|||
On most distributions, the distutils module is included in
|
||||
an extra ``python-dev`` package.
|
||||
|
||||
3. Qt development tools
|
||||
|
||||
The binary "qcollectiongenerator" is used to generate the
|
||||
documentation files.
|
||||
On Debian or Ubuntu systems, install the package qt4-dev-tools.
|
||||
On Redhat systems, install the package qt-devel.
|
||||
3. Python requests module from https://pypi.python.org/pypi/requests
|
||||
|
||||
4. Python requests module from https://pypi.python.org/pypi/requests
|
||||
|
||||
5. *Optional, for bash-completion:*
|
||||
4. *Optional, for bash-completion:*
|
||||
argcomplete Python module from https://pypi.python.org/pypi/argcomplete
|
||||
|
||||
6. *Optional, for displaying country codes:*
|
||||
5. *Optional, for displaying country codes:*
|
||||
GeoIP from http://www.maxmind.com/app/python
|
||||
|
||||
7. *Optional, used for Virus checking:*
|
||||
6. *Optional, used for Virus checking:*
|
||||
ClamAv from http://www.clamav.net/
|
||||
|
||||
8. *Optional, for GNOME proxy setting parsing:*
|
||||
7. *Optional, for GNOME proxy setting parsing:*
|
||||
Python Gtk from http://www.pygtk.org/downloads.html
|
||||
|
||||
9. *Optional, to run the WSGI web interface:*
|
||||
8. *Optional, to run the WSGI web interface:*
|
||||
Apache from http://httpd.apache.org/
|
||||
mod_wsgi from http://code.google.com/p/modwsgi/
|
||||
|
||||
|
||||
Now install the application.
|
||||
|
||||
1. Generate Qt documentation
|
||||
|
||||
Run ``make -C doc/html`` to generate the Qt help file.
|
||||
|
||||
2. Compile Python modules
|
||||
1. Compile Python modules
|
||||
|
||||
Run ``python setup.py sdist --manifest-only`` to create the MANIFEST
|
||||
file.
|
||||
|
|
@ -97,7 +86,7 @@ Now install the application.
|
|||
The CC environment variable is checked before compilation, so you can
|
||||
change the default C compiler with ``export CC=myccompiler``.
|
||||
|
||||
3.
|
||||
2.
|
||||
a) Installation as root
|
||||
|
||||
Run ``sudo python setup.py install`` to install LinkChecker.
|
||||
|
|
@ -134,7 +123,6 @@ Manual setup for OSX systems
|
|||
|
||||
brew update
|
||||
brew install python
|
||||
brew install pyqt
|
||||
brew install gettext
|
||||
# link gettext or put the msgfmt binary in your PATH
|
||||
brew link --force gettext
|
||||
|
|
|
|||
|
|
@ -1,11 +0,0 @@
|
|||
--- linkchecker-gui.1.html.orig 2011-06-14 21:22:16.160383430 +0200
|
||||
+++ linkchecker-gui.1.html 2011-06-14 21:22:23.120641725 +0200
|
||||
@@ -45,7 +45,7 @@
|
||||
</DL>
|
||||
<HR>
|
||||
This document was created by
|
||||
-<A HREF="/cgi-bin/man/man2html">man2html</A>,
|
||||
+man2html,
|
||||
using the manual pages.<BR>
|
||||
|
||||
</BODY>
|
||||
|
|
@ -1,10 +0,0 @@
|
|||
[Desktop Entry]
|
||||
Name=LinkChecker GUI
|
||||
GenericName=URL validator
|
||||
GenericName[de]=URL Validator
|
||||
Version=1.0
|
||||
Type=Application
|
||||
Exec=linkchecker-gui
|
||||
Terminal=false
|
||||
Categories=Network;WebDevelopment;
|
||||
Icon=logo48x48
|
||||
|
|
@ -2,4 +2,3 @@
|
|||
[po4a_paths] linkchecker.doc.pot $lang:$lang.po
|
||||
[type: man] en/linkchecker.1 $lang:$lang/linkchecker.1
|
||||
[type: man] en/linkcheckerrc.5 $lang:$lang/linkcheckerrc.5
|
||||
[type: man] en/linkchecker-gui.1 $lang:$lang/linkchecker-gui.1
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@ Porting status of dependent Python packages
|
|||
|
||||
OK Python
|
||||
OK requests
|
||||
OK Qt/PyQt
|
||||
OK mod_wsgi from http://code.google.com/p/modwsgi/
|
||||
OK argcomplete from https://pypi.python.org/pypi/argcomplete
|
||||
OK dnspython (as dnspython3)
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ Features
|
|||
- [Plugin support](plugins.html)
|
||||
allowing custom page checks. Currently available are
|
||||
HTML and CSS syntax checks, Antivirus checks, and more.
|
||||
- Different interfaces: command line, GUI and web interface
|
||||
- Different interfaces: command line and web interface
|
||||
- ... and a lot more check options documented in the
|
||||
[manual page](man1/linkchecker.1.html).
|
||||
|
||||
|
|
@ -35,15 +35,14 @@ Features
|
|||
Screenshots
|
||||
------------
|
||||
|
||||
[](images/shot1.png) | [](images/shot2.png) | [](images/shot3.png)
|
||||
--------------------------------------------------------------|---------------------------------------------------------------|--------------------------------------------------------------
|
||||
Commandline interface | GUI client | CGI web interface
|
||||
[](images/shot1.png) | [](images/shot3.png)
|
||||
--------------------------------------------------------------|--------------------------------------------------------------
|
||||
Commandline interface | CGI web interface
|
||||
|
||||
Basic usage
|
||||
------------
|
||||
To check a URL like `http://www.example.org/myhomepage/` it is enough to
|
||||
enter `http://www.example.org/myhomepage/` in the GUI client or
|
||||
web interface, or execute
|
||||
enter `http://www.example.org/myhomepage/` in the web interface, or execute
|
||||
`linkchecker http://www.example.org/myhomepage/` on the command line.
|
||||
|
||||
This check will validate recursively all pages starting with
|
||||
|
|
|
|||
|
|
@ -2,11 +2,8 @@ title: "Other free link checkers"
|
|||
---
|
||||
All of the programs below have an
|
||||
[Open Source license](http://www.opensource.org/licenses/) like LinkChecker.
|
||||
Programs without an Open Source license are not mentioned here for
|
||||
security and copyright reasons.
|
||||
|
||||
Also not mentioned are programs which have not been updated for
|
||||
more than 10 years.
|
||||
Programs without an Open Source license are not listed, as well as
|
||||
programs which have not been updated for more than 10 years.
|
||||
|
||||
- [gURLChecker](http://labs.libre-entreprise.org/projects/gurlchecker/)
|
||||
written in C, last updated February 22, 2011 (version 0.13.1)
|
||||
|
|
@ -14,5 +11,3 @@ more than 10 years.
|
|||
is an online service, but source is available, last updated 2011
|
||||
- [webcheck](http://arthurdejong.org/webcheck/)
|
||||
written in Python, last updated September 11, 2010 (version 1.10.4)
|
||||
- [webgrep](http://cgi.linuxfocus.org/~guido/index.html#webgrep)
|
||||
written in Perl, last updated April 2004 (version 2.12)
|
||||
|
|
|
|||
|
|
@ -1,59 +0,0 @@
|
|||
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
<HTML><HEAD><TITLE>Man page of LINKCHECKER-GUI</TITLE>
|
||||
</HEAD><BODY>
|
||||
<H1>LINKCHECKER-GUI</H1>
|
||||
Section: LinkChecker GUI client (1)<BR>Updated: 2009-01-10<BR><A HREF="#index">Index</A>
|
||||
<A HREF="../index.html">Return to Main Contents</A><HR>
|
||||
|
||||
<A NAME="lbAB"> </A>
|
||||
<H2>NAME</H2>
|
||||
|
||||
linkchecker-gui - GUI client to check links of websites and HTML documents
|
||||
<A NAME="lbAC"> </A>
|
||||
<H2>SYNOPSIS</H2>
|
||||
|
||||
<B>linkchecker-gui</B> [<I>file-or-url-or-project</I>]
|
||||
<A NAME="lbAD"> </A>
|
||||
<H2>DESCRIPTION</H2>
|
||||
|
||||
A graphical interface to check links of websites and HTML documents.
|
||||
<A NAME="lbAE"> </A>
|
||||
<H2>PROJECT FILES</H2>
|
||||
|
||||
A project file has a .lcp extension. The file stores all active preferences
|
||||
and the current checked URL. Project files can be loaded with the
|
||||
menu entry or with drag-and-drop on the GUI window.
|
||||
<P>
|
||||
<A NAME="lbAF"> </A>
|
||||
<H2>SEE ALSO</H2>
|
||||
|
||||
<B><A HREF="../man1/linkchecker.1.html">linkchecker</A></B>(1)
|
||||
<A NAME="lbAG"> </A>
|
||||
<H2>AUTHOR</H2>
|
||||
|
||||
Bastian Kleineidam <<A HREF="mailto:bastian.kleineidam@web.de">bastian.kleineidam@web.de</A>>
|
||||
<A NAME="lbAH"> </A>
|
||||
<H2>COPYRIGHT</H2>
|
||||
|
||||
Copyright © 2009-2014 Bastian Kleineidam
|
||||
<P>
|
||||
|
||||
<HR>
|
||||
<A NAME="index"> </A><H2>Index</H2>
|
||||
<DL>
|
||||
<DT><A HREF="#lbAB">NAME</A><DD>
|
||||
<DT><A HREF="#lbAC">SYNOPSIS</A><DD>
|
||||
<DT><A HREF="#lbAD">DESCRIPTION</A><DD>
|
||||
<DT><A HREF="#lbAE">PROJECT FILES</A><DD>
|
||||
<DT><A HREF="#lbAF">SEE ALSO</A><DD>
|
||||
<DT><A HREF="#lbAG">AUTHOR</A><DD>
|
||||
<DT><A HREF="#lbAH">COPYRIGHT</A><DD>
|
||||
</DL>
|
||||
<HR>
|
||||
This document was created by
|
||||
man2html,
|
||||
using the manual pages.<BR>
|
||||
|
||||
</BODY>
|
||||
</HTML>
|
||||
|
|
@ -44,22 +44,21 @@ HTML and CSS syntax check
|
|||
<DT>•<DD>
|
||||
Antivirus check
|
||||
<DT>•<DD>
|
||||
a command line, GUI and web interface
|
||||
a command line and web interface
|
||||
</DL>
|
||||
<A NAME="lbAE"> </A>
|
||||
<H2>EXAMPLES</H2>
|
||||
|
||||
The most common use checks the given domain recursively, plus any
|
||||
URL pointing outside of the domain:
|
||||
<BR> <B>linkchecker http://www.example.net/</B>
|
||||
The most common use checks the given domain recursively:
|
||||
<BR> <B>linkchecker <A HREF="http://www.example.com/">http://www.example.com/</A></B>
|
||||
<BR>
|
||||
|
||||
Beware that this checks the whole site which can have thousands of URLs.
|
||||
Use the <B>-r</B> option to restrict the recursion depth.
|
||||
<BR>
|
||||
|
||||
Don't check <B>mailto:</B> URLs. All other links are checked as usual:
|
||||
<BR> <B>linkchecker --ignore-url=^mailto: mysite.example.org</B>
|
||||
Don't check URLs with <B>/secret</B> in its name. All other links are checked as usual:
|
||||
<BR> <B>linkchecker --ignore-url=/secret mysite.example.com</B>
|
||||
<BR>
|
||||
|
||||
Checking a local HTML file on Unix:
|
||||
|
|
@ -71,15 +70,15 @@ Checking a local HTML file on Windows:
|
|||
<BR>
|
||||
|
||||
You can skip the <B>http://</B> url part if the domain starts with <B>www.</B>:
|
||||
<BR> <B>linkchecker www.example.com</B>
|
||||
<BR> <B>linkchecker <A HREF="http://www.example.com">www.example.com</A></B>
|
||||
<BR>
|
||||
|
||||
You can skip the <B>ftp://</B> url part if the domain starts with <B>ftp.</B>:
|
||||
<BR> <B>linkchecker -r0 ftp.example.org</B>
|
||||
<BR> <B>linkchecker -r0 <A HREF="ftp://ftp.example.com">ftp.example.com</A></B>
|
||||
<BR>
|
||||
|
||||
Generate a sitemap graph and convert it with the graphviz dot utility:
|
||||
<BR> <B>linkchecker -odot -v www.example.com | dot -Tps > sitemap.ps</B>
|
||||
<BR> <B>linkchecker -odot -v <A HREF="http://www.example.com">www.example.com</A> | dot -Tps > sitemap.ps</B>
|
||||
<A NAME="lbAF"> </A>
|
||||
<H2>OPTIONS</H2>
|
||||
|
||||
|
|
@ -99,21 +98,17 @@ Generate no more than the given number of threads. Default number
|
|||
of threads is 10. To disable threading specify a non-positive number.
|
||||
<DT><B>-V</B>, <B>--version</B><DD>
|
||||
Print version and exit.
|
||||
<DT><B>--list-plugins</B><DD>
|
||||
Print available check plugins and exit.
|
||||
</DL>
|
||||
<A NAME="lbAH"> </A>
|
||||
<H3>Output options</H3>
|
||||
|
||||
<DL COMPACT>
|
||||
<DT><B>--check-css</B><DD>
|
||||
Check syntax of CSS URLs with the W3C online validator.
|
||||
<DT><B>--check-html</B><DD>
|
||||
Check syntax of HTML URLs with the W3C online validator.
|
||||
<DT><B>--complete</B><DD>
|
||||
Log all URLs, including duplicates. Default is to log duplicate URLs only once.
|
||||
<DT><B>-D</B><I>STRING</I>, <B>--debug=</B><I>STRING</I><DD>
|
||||
Print debugging output for the given logger.
|
||||
Available loggers are <B>cmdline</B>, <B>checking</B>,
|
||||
<B>cache</B>, <B>gui</B>, <B>dns</B> and <B>all</B>.
|
||||
<B>cache</B>, <B>dns</B> and <B>all</B>.
|
||||
Specifying <B>all</B> is an alias for specifying all available loggers.
|
||||
The option can be given multiple times to debug with more
|
||||
than one logger.
|
||||
|
|
@ -156,10 +151,6 @@ that of your locale. Valid encodings are listed at
|
|||
<DT><B>-q</B>, <B>--quiet</B><DD>
|
||||
Quiet operation, an alias for <B>-o none</B>.
|
||||
This is only useful with <B>-F</B>.
|
||||
<DT><B>--scan-virus</B><DD>
|
||||
Scan content of URLs for viruses with ClamAV.
|
||||
<DT><B>--trace</B><DD>
|
||||
Print tracing information.
|
||||
<DT><B>-v</B>, <B>--verbose</B><DD>
|
||||
Log all checked URLs. Default is to log only errors and warnings.
|
||||
<DT><B>-W</B><I>REGEX</I>, <B>--warning-regex=</B><I>REGEX</I><DD>
|
||||
|
|
@ -177,26 +168,17 @@ for example "(This page has moved|Oracle Application error)".
|
|||
<BR>
|
||||
|
||||
See section <B>REGULAR EXPRESSIONS</B> for more info.
|
||||
<DT><B>--warning-size-bytes=</B><I>NUMBER</I><DD>
|
||||
Print a warning if content size info is available and exceeds the given
|
||||
number of <I>bytes</I>.
|
||||
</DL>
|
||||
<A NAME="lbAI"> </A>
|
||||
<H3>Checking options</H3>
|
||||
|
||||
<DL COMPACT>
|
||||
<DT><B>-a</B>, <B>--anchors</B><DD>
|
||||
Check HTTP anchor references. Default is not to check anchors.
|
||||
This option enables logging of the warning <B>url-anchor-not-found</B>.
|
||||
<DT><B>-C</B>, <B>--cookies</B><DD>
|
||||
Accept and send HTTP cookies according to RFC 2109. Only cookies
|
||||
which are sent back to the originating server are accepted.
|
||||
Sent and accepted cookies are provided as additional logging
|
||||
information.
|
||||
<DT><B>--cookiefile=</B><I>FILENAME</I><DD>
|
||||
Read a file with initial cookie data. The cookie data
|
||||
format is explained below.
|
||||
<DT><B>--ignore-url=</B><I>REGEX</I><DD>
|
||||
<DT><B>--check-extern<DD>
|
||||
Check external URLs.
|
||||
<DT>--ignore-url=</B><I>REGEX</I><DD>
|
||||
URLs matching the given regular expression will be ignored and not checked.
|
||||
<BR>
|
||||
|
||||
|
|
@ -221,9 +203,6 @@ See section <B>REGULAR EXPRESSIONS</B> for more info.
|
|||
Read a password from console and use it for HTTP and FTP authorization.
|
||||
For FTP the default password is <B>anonymous@</B>. For HTTP there is
|
||||
no default password. See also <B>-u</B>.
|
||||
<DT><B>-P</B><I>NUMBER</I>, <B>--pause=</B><I>NUMBER</I><DD>
|
||||
Pause the given number of seconds between two subsequent connection
|
||||
requests to the same host. Default is no pause between requests.
|
||||
<DT><B>-r</B><I>NUMBER</I>, <B>--recursion-level=</B><I>NUMBER</I><DD>
|
||||
Check recursively all links up to given depth.
|
||||
A negative depth will enable infinite recursion.
|
||||
|
|
@ -299,13 +278,11 @@ expression.
|
|||
A cookie file contains standard HTTP header (RFC 2616) data with the
|
||||
following possible names:
|
||||
<DL COMPACT>
|
||||
<DT><B>Scheme</B> (optional)<DD>
|
||||
Sets the scheme the cookies are valid for; default scheme is <B>http</B>.
|
||||
<DT><B>Host</B> (required)<DD>
|
||||
Sets the domain the cookies are valid for.
|
||||
<DT><B>Path</B> (optional)<DD>
|
||||
Gives the path the cookies are value for; default path is <B>/</B>.
|
||||
<DT><B>Set-cookie</B> (optional)<DD>
|
||||
<DT><B>Set-cookie</B> (required)<DD>
|
||||
Set cookie name/value. Can be given more than once.
|
||||
</DL>
|
||||
<P>
|
||||
|
|
@ -320,7 +297,6 @@ with <B>https://example.org/</B>:
|
|||
<BR> Set-cookie: ID="smee"
|
||||
<BR> Set-cookie: spam="egg"
|
||||
<P>
|
||||
<BR> Scheme: https
|
||||
<BR> Host: example.org
|
||||
<BR> Set-cookie: baggage="elitist"; comment="hologram"
|
||||
<P>
|
||||
|
|
@ -331,7 +307,8 @@ To use a proxy on Unix or Windows set the $http_proxy, $https_proxy or $ftp_prox
|
|||
environment variables to the proxy URL. The URL should be of the form
|
||||
<B>http://</B>[<I>user</I><B>:</B><I>pass</I><B>@</B>]<I>host</I>[<B>:</B><I>port</I>].
|
||||
LinkChecker also detects manual proxy settings of Internet Explorer under
|
||||
Windows systems. On a Mac use the Internet Config to select a proxy.
|
||||
Windows systems, and gconf or KDE on Linux systems.
|
||||
On a Mac use the Internet Config to select a proxy.
|
||||
You can also set a comma-separated domain list in the $no_proxy environment
|
||||
variables to ignore any proxy settings for these domains.
|
||||
Setting a HTTP proxy on Unix for example looks like this:
|
||||
|
|
@ -360,7 +337,6 @@ After connecting to the given HTTP server the given path
|
|||
or query is requested. All redirections are followed, and
|
||||
if user/password is given it will be used as authorization
|
||||
when necessary.
|
||||
Permanently moved pages issue a warning.
|
||||
All final HTTP status codes other than 2xx are errors.
|
||||
HTML page contents are checked for recursion.
|
||||
<DT>Local files (<B>file:</B>)<DD>
|
||||
|
|
@ -412,6 +388,19 @@ For each mail address we check the following things:
|
|||
<P>
|
||||
</DL>
|
||||
<A NAME="lbAP"> </A>
|
||||
<H2>PLUGINS</H2>
|
||||
|
||||
There are two plugin types: connection and content plugins.
|
||||
Connection plugins are run after a successful connection to the
|
||||
URL host.
|
||||
Content plugins are run if the URL type has content
|
||||
(mailto: URLs have no content for example) and if the check is not
|
||||
forbidden (ie. by HTTP robots.txt).
|
||||
See <B>linkchecker --list-plugins</B> for a list of plugins and
|
||||
their documentation. All plugins are enabled via the <B><A HREF="../man5/linkcheckerrc.5.html">linkcheckerrc</A></B>(5)
|
||||
configuration file.
|
||||
<P>
|
||||
<A NAME="lbAQ"> </A>
|
||||
<H2>RECURSION</H2>
|
||||
|
||||
Before descending recursively into a URL, it has to fulfill several
|
||||
|
|
@ -441,7 +430,7 @@ conditions. They are checked in this order:
|
|||
Note that the directory recursion reads all files in that
|
||||
directory, not just a subset like <B>index.htm*</B>.
|
||||
<P>
|
||||
<A NAME="lbAQ"> </A>
|
||||
<A NAME="lbAR"> </A>
|
||||
<H2>NOTES</H2>
|
||||
|
||||
URLs on the commandline starting with <B>ftp.</B> are treated like
|
||||
|
|
@ -463,7 +452,7 @@ You can supply multiple user/password pairs in a configuration file.
|
|||
<P>
|
||||
When checking <B>news:</B> links the given NNTP host doesn't need to be the
|
||||
same as the host of the user browsing your pages.
|
||||
<A NAME="lbAR"> </A>
|
||||
<A NAME="lbAS"> </A>
|
||||
<H2>ENVIRONMENT</H2>
|
||||
|
||||
<B>NNTP_SERVER</B> - specifies default NNTP server
|
||||
|
|
@ -479,7 +468,7 @@ same as the host of the user browsing your pages.
|
|||
<BR>
|
||||
|
||||
<B>LC_MESSAGES</B>, <B>LANG</B>, <B>LANGUAGE</B> - specify output language
|
||||
<A NAME="lbAS"> </A>
|
||||
<A NAME="lbAT"> </A>
|
||||
<H2>RETURN VALUE</H2>
|
||||
|
||||
The return value is 2 when
|
||||
|
|
@ -499,13 +488,13 @@ link warnings were found and warnings are enabled
|
|||
<P>
|
||||
|
||||
Else the return value is zero.
|
||||
<A NAME="lbAT"> </A>
|
||||
<A NAME="lbAU"> </A>
|
||||
<H2>LIMITATIONS</H2>
|
||||
|
||||
LinkChecker consumes memory for each queued URL to check. With thousands
|
||||
of queued URLs the amount of consumed memory can become quite large. This
|
||||
might slow down the program or even the whole system.
|
||||
<A NAME="lbAU"> </A>
|
||||
<A NAME="lbAV"> </A>
|
||||
<H2>FILES</H2>
|
||||
|
||||
<B>~/.linkchecker/linkcheckerrc</B> - default configuration file
|
||||
|
|
@ -522,15 +511,15 @@ might slow down the program or even the whole system.
|
|||
|
||||
<B><A HREF="http://docs.python.org/howto/regex.html">http://docs.python.org/howto/regex.html</A></B> - regular expression documentation
|
||||
<P>
|
||||
<A NAME="lbAV"> </A>
|
||||
<A NAME="lbAW"> </A>
|
||||
<H2>SEE ALSO</H2>
|
||||
|
||||
<B><A HREF="../man5/linkcheckerrc.5.html">linkcheckerrc</A></B>(5)
|
||||
<A NAME="lbAW"> </A>
|
||||
<A NAME="lbAX"> </A>
|
||||
<H2>AUTHOR</H2>
|
||||
|
||||
Bastian Kleineidam <<A HREF="mailto:bastian.kleineidam@web.de">bastian.kleineidam@web.de</A>>
|
||||
<A NAME="lbAX"> </A>
|
||||
<A NAME="lbAY"> </A>
|
||||
<H2>COPYRIGHT</H2>
|
||||
|
||||
Copyright © 2000-2014 Bastian Kleineidam
|
||||
|
|
@ -555,15 +544,16 @@ Copyright © 2000-2014 Bastian Kleineidam
|
|||
<DT><A HREF="#lbAM">COOKIE FILES</A><DD>
|
||||
<DT><A HREF="#lbAN">PROXY SUPPORT</A><DD>
|
||||
<DT><A HREF="#lbAO">PERFORMED CHECKS</A><DD>
|
||||
<DT><A HREF="#lbAP">RECURSION</A><DD>
|
||||
<DT><A HREF="#lbAQ">NOTES</A><DD>
|
||||
<DT><A HREF="#lbAR">ENVIRONMENT</A><DD>
|
||||
<DT><A HREF="#lbAS">RETURN VALUE</A><DD>
|
||||
<DT><A HREF="#lbAT">LIMITATIONS</A><DD>
|
||||
<DT><A HREF="#lbAU">FILES</A><DD>
|
||||
<DT><A HREF="#lbAV">SEE ALSO</A><DD>
|
||||
<DT><A HREF="#lbAW">AUTHOR</A><DD>
|
||||
<DT><A HREF="#lbAX">COPYRIGHT</A><DD>
|
||||
<DT><A HREF="#lbAP">PLUGINS</A><DD>
|
||||
<DT><A HREF="#lbAQ">RECURSION</A><DD>
|
||||
<DT><A HREF="#lbAR">NOTES</A><DD>
|
||||
<DT><A HREF="#lbAS">ENVIRONMENT</A><DD>
|
||||
<DT><A HREF="#lbAT">RETURN VALUE</A><DD>
|
||||
<DT><A HREF="#lbAU">LIMITATIONS</A><DD>
|
||||
<DT><A HREF="#lbAV">FILES</A><DD>
|
||||
<DT><A HREF="#lbAW">SEE ALSO</A><DD>
|
||||
<DT><A HREF="#lbAX">AUTHOR</A><DD>
|
||||
<DT><A HREF="#lbAY">COPYRIGHT</A><DD>
|
||||
</DL>
|
||||
<HR>
|
||||
This document was created by
|
||||
|
|
|
|||
30
doc/web/media/man1/linkchecker.1.html.rej
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
--- linkchecker.1.html.orig 2011-06-14 21:14:55.016011206 +0200
|
||||
+++ linkchecker.1.html 2011-06-14 21:17:07.108913849 +0200
|
||||
@@ -38,7 +38,7 @@
|
||||
|
||||
The most common use checks the given domain recursively, plus any
|
||||
URL pointing outside of the domain:
|
||||
-<BR> <B>linkchecker <A HREF="http://www.example.net/">http://www.example.net/</A></B>
|
||||
+<BR> <B>linkchecker http://www.example.net/</B>
|
||||
<BR>
|
||||
|
||||
Beware that this checks the whole site which can have thousands of URLs.
|
||||
@@ -59,15 +59,15 @@
|
||||
<BR>
|
||||
|
||||
You can skip the <B>http://</B> url part if the domain starts with <B>www.</B>:
|
||||
-<BR> <B>linkchecker <A HREF="http://www.example.com">www.example.com</A></B>
|
||||
+<BR> <B>linkchecker www.example.com</B>
|
||||
<BR>
|
||||
|
||||
You can skip the <B>ftp://</B> url part if the domain starts with <B>ftp.</B>:
|
||||
-<BR> <B>linkchecker -r0 <A HREF="ftp://ftp.example.org">ftp.example.org</A></B>
|
||||
+<BR> <B>linkchecker -r0 ftp.example.org</B>
|
||||
<BR>
|
||||
|
||||
Generate a sitemap graph and convert it with the graphviz dot utility:
|
||||
-<BR> <B>linkchecker -odot -v <A HREF="http://www.example.com">www.example.com</A> | dot -Tps > sitemap.ps</B>
|
||||
+<BR> <B>linkchecker -odot -v www.example.com | dot -Tps > sitemap.ps</B>
|
||||
<A NAME="lbAF"> </A>
|
||||
<H2>OPTIONS</H2>
|
||||
|
||||
|
|
@ -155,7 +155,7 @@ The default number of days is 14.
|
|||
Command line option: none
|
||||
<DT><B>maxrunseconds=</B><I>NUMBER</I><DD>
|
||||
Stop checking new URLs after the given number of seconds. Same as if the
|
||||
user stops (by hitting Ctrl-C or clicking the abort buttin in the GUI)
|
||||
user stops (by hitting Ctrl-C)
|
||||
after the given number of seconds.
|
||||
<BR>
|
||||
|
||||
|
|
@ -273,7 +273,7 @@ Command line option: <B>--complete</B>
|
|||
<DT><B>debug=</B><I>STRING</I>[<B>,</B><I>STRING</I>...]<DD>
|
||||
Print debugging output for the given loggers.
|
||||
Available loggers are <B>cmdline</B>, <B>checking</B>,
|
||||
<B>cache</B>, <B>gui</B>, <B>dns</B>, <B>thread</B> and <B>all</B>.
|
||||
<B>cache</B>, <B>dns</B>, <B>thread</B> and <B>all</B>.
|
||||
Specifying <B>all</B> is an alias for specifying all available loggers.
|
||||
<BR>
|
||||
|
||||
|
|
|
|||
|
|
@ -45,7 +45,6 @@ from .logconf import (
|
|||
LOG_CMDLINE,
|
||||
LOG_CHECK,
|
||||
LOG_CACHE,
|
||||
LOG_GUI,
|
||||
LOG_THREAD,
|
||||
LOG_PLUGIN,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -61,35 +61,35 @@ def normpath (path):
|
|||
return os.path.normcase(os.path.normpath(expanded))
|
||||
|
||||
|
||||
# List optional Python modules in the form (module, name)
|
||||
# List Python modules in the form (module, name, version attribute)
|
||||
Modules = (
|
||||
("PyQt4.Qsci", u"QScintilla"),
|
||||
("argcomplete", u"Argcomplete"),
|
||||
("GeoIP", u"GeoIP"), # on Unix systems
|
||||
("pygeoip", u"GeoIP"), # on Windows systems
|
||||
("sqlite3", u"Sqlite"),
|
||||
("gconf", u"Gconf"),
|
||||
("meliae", u"Meliae"),
|
||||
# required modules
|
||||
("requests", "Requests", "__version__"),
|
||||
# optional modules
|
||||
("argcomplete", u"Argcomplete", None),
|
||||
("GeoIP", u"GeoIP", 'lib_version'), # on Unix systems
|
||||
("pygeoip", u"GeoIP", 'lib_version'), # on Windows systems
|
||||
("sqlite3", u"Pysqlite", 'version'),
|
||||
("sqlite3", u"Sqlite", 'sqlite_version'),
|
||||
("gconf", u"Gconf", '__version__'),
|
||||
("meliae", u"Meliae", '__version__'),
|
||||
)
|
||||
|
||||
def get_modules_info ():
|
||||
"""Return list of unicode strings with detected module info."""
|
||||
lines = []
|
||||
# requests
|
||||
import requests
|
||||
lines.append(u"Requests: %s" % requests.__version__)
|
||||
# PyQt
|
||||
try:
|
||||
from PyQt4 import QtCore
|
||||
lines.append(u"Qt: %s / PyQt: %s" %
|
||||
(QtCore.QT_VERSION_STR, QtCore.PYQT_VERSION_STR))
|
||||
except (ImportError, AttributeError):
|
||||
pass
|
||||
# modules
|
||||
modules = [name for (mod, name) in Modules if fileutil.has_module(mod)]
|
||||
if modules:
|
||||
lines.append(u"Modules: %s" % (u", ".join(modules)))
|
||||
return lines
|
||||
def get_modules_info():
|
||||
"""Return unicode string with detected module info."""
|
||||
module_infos = []
|
||||
for (mod, name, version_attr) in Modules:
|
||||
if not fileutil.has_module(mod):
|
||||
continue
|
||||
if hasattr(mod, version_attr):
|
||||
attr = getattr(mod, version_attr)
|
||||
version = attr() if callable(attr) else attr
|
||||
module_infos.append("%s %s" % (name, version))
|
||||
else:
|
||||
# ignore attribute errors in case library developers
|
||||
# change the version information attribute
|
||||
module_infos.append(name)
|
||||
return u"Modules: %s" % (u", ".join(module_infos))
|
||||
|
||||
|
||||
def get_share_dir ():
|
||||
|
|
|
|||
|
|
@ -149,8 +149,7 @@ def print_app_info (out=stderr):
|
|||
{"version": sys.version, "platform": sys.platform}, file=out)
|
||||
for key in PYTHON_ENV_VARS:
|
||||
print_env_info(key, out=out)
|
||||
for line in configuration.get_modules_info():
|
||||
print(line, file=out)
|
||||
print(configuration.get_modules_info(), file=out)
|
||||
stime = strformat.strtime(time.time())
|
||||
print(_("Local time:"), stime, file=out)
|
||||
print(_("sys.argv:"), sys.argv, file=out)
|
||||
|
|
|
|||
|
|
@ -1,26 +0,0 @@
|
|||
# generate Python files from UI description
|
||||
|
||||
# edit ui/*.ui files with designer (ie. /usr/bin/designer-qt4)
|
||||
UI_FILES = linkchecker_ui_main.py \
|
||||
linkchecker_ui_options.py \
|
||||
linkchecker_ui_debug.py \
|
||||
linkchecker_ui_editor.py
|
||||
RC_FILES = linkchecker_rc.py
|
||||
|
||||
|
||||
all: $(UI_FILES) $(RC_FILES)
|
||||
|
||||
linkchecker_ui_%.py: ui/%.ui
|
||||
pyuic4 -o $@ $<
|
||||
# replace the Qt translator with the one LinkChecker uses
|
||||
sed -i -r -e 's/QtGui\.QApplication\.translate\("[^"]+", "([^"]+)", None, QtGui\.QApplication\.UnicodeUTF8\)/_("\1")/g' $@
|
||||
|
||||
linkchecker_rc.py: rc/linkchecker.qrc
|
||||
pyrcc4 -o $@ $<
|
||||
|
||||
clean:
|
||||
rm -f *.pyc *.pyo
|
||||
|
||||
rebuild:
|
||||
rm -f $(UI_FILES) $(RC_FILES)
|
||||
$(MAKE) all
|
||||
|
|
@ -1,623 +0,0 @@
|
|||
# -*- coding: iso-8859-1 -*-
|
||||
# Copyright (C) 2008-2014 Bastian Kleineidam
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along
|
||||
# with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
import os
|
||||
import sys
|
||||
import re
|
||||
import webbrowser
|
||||
from PyQt4 import QtCore, QtGui
|
||||
from .linkchecker_ui_main import Ui_MainWindow
|
||||
from .properties import set_properties, clear_properties
|
||||
from .statistics import set_statistics, clear_statistics
|
||||
from .debug import LinkCheckerDebug
|
||||
from .logger import SignalLogger, GuiLogHandler, StatusLogger
|
||||
from .help import HelpWindow
|
||||
from .options import LinkCheckerOptions
|
||||
from .checker import CheckerThread
|
||||
from .contextmenu import ContextMenu
|
||||
from .editor import EditorWindow
|
||||
from .updater import UpdateDialog
|
||||
from .urlmodel import UrlItemModel
|
||||
from .urlsave import urlsave
|
||||
from .settings import Settings
|
||||
from .recentdocs import RecentDocumentModel
|
||||
from .projects import openproject, saveproject, loadproject, ProjectExt
|
||||
from .. import configuration, checker, director, get_link_pat, \
|
||||
strformat, mimeutil, LinkCheckerError, i18n, httputil, logconf
|
||||
from ..containers import enum
|
||||
from .. import url as urlutil
|
||||
|
||||
|
||||
DocBaseUrl = "qthelp://bfk.app.linkchecker/doc/"
|
||||
RegistryBase = "Bastian"
|
||||
Status = enum('idle', 'checking')
|
||||
|
||||
MaxMessageLength = 60
|
||||
|
||||
def get_app_style ():
|
||||
"""Return appropriate QStyle object for the current platform to
|
||||
be used in QApplication.setStyle().
|
||||
Currently prefers Macintosh on OS X, else Plastique.
|
||||
Style names are case insensitive.
|
||||
|
||||
See also
|
||||
http://doc.trolltech.com/latest/gallery-macintosh.html
|
||||
and
|
||||
http://doc.trolltech.com/latest/gallery-plastique.html
|
||||
"""
|
||||
if sys.platform == 'darwin':
|
||||
style = "Macintosh"
|
||||
else:
|
||||
style = "Plastique"
|
||||
return QtGui.QStyleFactory.create(style)
|
||||
|
||||
|
||||
def get_icon (name):
|
||||
"""Return QIcon with given pixmap resource name."""
|
||||
icon = QtGui.QIcon()
|
||||
icon.addPixmap(QtGui.QPixmap(name), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
return icon
|
||||
|
||||
|
||||
def warninglines2regex(lines):
|
||||
"""Convert a list of strings to a regular expression matching any of
|
||||
the given strings."""
|
||||
return u"|".join([re.escape(line) for line in lines])
|
||||
|
||||
|
||||
class LinkCheckerMain (QtGui.QMainWindow, Ui_MainWindow):
|
||||
"""The main window displaying checked URLs."""
|
||||
|
||||
log_url_signal = QtCore.pyqtSignal(object)
|
||||
log_status_signal = QtCore.pyqtSignal(int, int, int, float, int)
|
||||
log_stats_signal = QtCore.pyqtSignal(object)
|
||||
error_signal = QtCore.pyqtSignal(str)
|
||||
|
||||
def __init__(self, parent=None, url=None, project=None):
|
||||
"""Initialize UI."""
|
||||
super(LinkCheckerMain, self).__init__(parent)
|
||||
self.setupUi(self)
|
||||
self.setWindowFlags(self.windowFlags() | QtCore.Qt.WindowContextHelpButtonHint)
|
||||
self.setWindowTitle(configuration.App)
|
||||
# app settings
|
||||
self.settings = Settings(RegistryBase, configuration.AppName)
|
||||
# init subdialogs
|
||||
self.options = LinkCheckerOptions(parent=self)
|
||||
self.debug = LinkCheckerDebug(parent=self)
|
||||
self.checker = CheckerThread(parent=self)
|
||||
self.contextmenu = ContextMenu(parent=self)
|
||||
self.editor = EditorWindow(parent=self)
|
||||
# Note: do not use QT assistant here because of the .exe packaging
|
||||
self.assistant = HelpWindow(self, self.get_qhcpath())
|
||||
self.config_error = None
|
||||
self.icon_start = get_icon(":/icons/start.png")
|
||||
self.icon_stop = get_icon(":/icons/stop.png")
|
||||
self.movie = QtGui.QMovie(":/icons/busy.gif")
|
||||
self.movie.setCacheMode(QtGui.QMovie.CacheAll)
|
||||
self.label_busy.setText(u"")
|
||||
self.label_busy.setMovie(self.movie)
|
||||
# init the rest
|
||||
self.init_logging()
|
||||
self.init_url(url)
|
||||
self.init_treeview()
|
||||
self.connect_widgets()
|
||||
self.init_shortcuts()
|
||||
self.init_config()
|
||||
self.read_config()
|
||||
self.init_menu()
|
||||
self.init_drop()
|
||||
self.init_app(project)
|
||||
|
||||
def init_logging(self):
|
||||
"""Initialize logging."""
|
||||
self.handler = GuiLogHandler(self.debug.log_msg_signal)
|
||||
logconf.init_log_config(handler=self.handler)
|
||||
|
||||
def init_url (self, url):
|
||||
"""Initialize URL input."""
|
||||
documents = self.settings.read_recent_documents()
|
||||
self.recent = RecentDocumentModel(parent=self, documents=documents)
|
||||
self.urlinput.setModel(self.recent)
|
||||
if url:
|
||||
self.urlinput.setText(url)
|
||||
elif documents:
|
||||
self.urlinput.setText(documents[0])
|
||||
|
||||
def init_menu (self):
|
||||
"""Add menu entries for bookmark file checking."""
|
||||
self.urlinput.addMenuEntries(self.menuEdit)
|
||||
self.menuLang = self.menuEdit.addMenu(_('Languages'))
|
||||
self.menuLang.setTitle(_("&Language"))
|
||||
# ensure only one action is checked
|
||||
langActionGroup = QtGui.QActionGroup(self)
|
||||
langActionGroup.triggered.connect(self.switch_language)
|
||||
for i, lang in enumerate(sorted(i18n.supported_languages)):
|
||||
action = self.menuLang.addAction("&%d %s" % (i, lang))
|
||||
action.setCheckable(True)
|
||||
action.setData(lang)
|
||||
if lang == i18n.default_language:
|
||||
action.setChecked(True)
|
||||
langActionGroup.addAction(action)
|
||||
|
||||
def init_drop(self):
|
||||
"""Set and activate drag-and-drop functions."""
|
||||
self.__class__.dragEnterEvent = self.handleDragEvent
|
||||
self.__class__.dragMoveEvent = self.handleDragEvent
|
||||
self.__class__.dropEvent = self.handleDropEvent
|
||||
self.setAcceptDrops(True)
|
||||
|
||||
def init_app (self, project):
|
||||
"""Set window size and position, GUI options and reset status."""
|
||||
data = self.settings.read_geometry()
|
||||
if data["size"] is not None:
|
||||
self.resize(data["size"])
|
||||
if data["pos"] is not None:
|
||||
self.move(data["pos"])
|
||||
self.options.set_options(self.settings.read_options())
|
||||
self.status = Status.idle
|
||||
self.actionSave.setEnabled(False)
|
||||
if project:
|
||||
loadproject(self, project)
|
||||
else:
|
||||
msg = self.config_error or _("Ready.")
|
||||
self.set_statusmsg(msg)
|
||||
data = self.settings.read_misc()
|
||||
self.saveresultas = data['saveresultas']
|
||||
|
||||
def get_qhcpath (self):
|
||||
"""Helper function to search for the QHC help file in different
|
||||
locations."""
|
||||
devel_dir = os.path.join(configuration.configdata.install_data, "doc", "html")
|
||||
return configuration.get_share_file('lccollection.qhc', devel_dir=devel_dir)
|
||||
|
||||
def connect_widgets (self):
|
||||
"""Connect widget signals. Some signals use the AutoConnect feature.
|
||||
Autoconnected methods have the form on_<objectname>_<signal>.
|
||||
"""
|
||||
def set_idle ():
|
||||
"""Set application status to idle."""
|
||||
self.status = Status.idle
|
||||
self.set_statusmsg(_("Check finished."))
|
||||
self.controlButton.clicked.disconnect(self.checker.cancel)
|
||||
self.checker.finished.connect(set_idle)
|
||||
self.checker.terminated.connect(set_idle)
|
||||
self.log_url_signal.connect(self.model.log_url)
|
||||
self.log_stats_signal.connect(self.log_stats)
|
||||
self.error_signal.connect(self.internal_error)
|
||||
self.options.editor.saved.connect(self.read_config)
|
||||
self.log_status_signal.connect(self.log_status)
|
||||
self.prop_url.linkHovered.connect(self.hover_link)
|
||||
self.prop_parenturl.linkHovered.connect(self.hover_link)
|
||||
|
||||
def init_shortcuts (self):
|
||||
"""Configure application shortcuts."""
|
||||
def selectUrl():
|
||||
"""Highlight URL input textbox."""
|
||||
self.urlinput.setFocus()
|
||||
self.urlinput.selectAll()
|
||||
shortcut = QtGui.QShortcut(QtGui.QKeySequence("Ctrl+L"), self)
|
||||
shortcut.activated.connect(selectUrl)
|
||||
|
||||
def init_treeview (self):
|
||||
"""Set treeview model and layout."""
|
||||
self.model = UrlItemModel()
|
||||
self.treeView.setModel(self.model)
|
||||
data = self.settings.read_treeviewcols()
|
||||
self.treeView.setColumnWidth(0, data["col1"])
|
||||
self.treeView.setColumnWidth(1, data["col2"])
|
||||
self.treeView.setColumnWidth(2, data["col3"])
|
||||
selectionModel = self.treeView.selectionModel()
|
||||
selectionModel.selectionChanged.connect(self.set_properties)
|
||||
|
||||
def get_treeviewcols (self):
|
||||
"""Return URL treeview column widths."""
|
||||
return dict(
|
||||
col1=self.treeView.columnWidth(0),
|
||||
col2=self.treeView.columnWidth(1),
|
||||
col3=self.treeView.columnWidth(2),
|
||||
)
|
||||
|
||||
def init_config (self):
|
||||
"""Create a configuration object."""
|
||||
self.config = configuration.Configuration()
|
||||
status = StatusLogger(self.log_status_signal)
|
||||
self.config.set_status_logger(status)
|
||||
# dictionary holding overwritten values
|
||||
self.config_backup = {}
|
||||
# set standard GUI configuration values
|
||||
self.config.logger_add(SignalLogger)
|
||||
self.config["logger"] = self.config.logger_new(SignalLogger.LoggerName,
|
||||
signal=self.log_url_signal, stats=self.log_stats_signal)
|
||||
self.config["status"] = True
|
||||
self.config["status_wait_seconds"] = 2
|
||||
|
||||
def read_config (self, filename=None):
|
||||
"""Read user and system configuration file."""
|
||||
try:
|
||||
self.config.read()
|
||||
except LinkCheckerError as msg:
|
||||
self.config_error = unicode(msg)
|
||||
|
||||
def set_config (self):
|
||||
"""Set configuration."""
|
||||
data = self.options.get_options()
|
||||
self.config["recursionlevel"] = data["recursionlevel"]
|
||||
self.config["verbose"] = data["verbose"]
|
||||
if data["debug"]:
|
||||
logconf.set_debug(["all"])
|
||||
# make sure at least one thread is used
|
||||
self.config["threads"] = 1
|
||||
else:
|
||||
logconf.reset_loglevel()
|
||||
if data["warninglines"]:
|
||||
lines = data["warninglines"].splitlines()
|
||||
pattern = warninglines2regex(lines)
|
||||
args = dict(warningregex=pattern)
|
||||
self.backup_config("enabledplugins", ["RegexCheck"])
|
||||
self.config["RegexCheck"] = args
|
||||
# set ignore patterns
|
||||
ignorepats = data["ignorelines"].strip()
|
||||
if ignorepats:
|
||||
self.backup_config("externlinks")
|
||||
lines = ignorepats.splitlines()
|
||||
for line in lines:
|
||||
try:
|
||||
pat = get_link_pat(line, strict=1)
|
||||
self.config["externlinks"].append(pat)
|
||||
except re.error as err:
|
||||
msg = _("Invalid regular expression %r: %s" % (pat, err))
|
||||
self.set_statusmsg(msg)
|
||||
# make sure the configuration is sane
|
||||
self.config.sanitize()
|
||||
|
||||
def backup_config (self, key, value=None):
|
||||
"""Backup config key if not already done and set given value."""
|
||||
if key not in self.config_backup:
|
||||
confvalue = self.config[key]
|
||||
if isinstance(confvalue, list):
|
||||
# make copy of lists to avoid unwanted inserted items
|
||||
confvalue = confvalue[:]
|
||||
self.config_backup[key] = confvalue
|
||||
if value is not None:
|
||||
self.config[key] = value
|
||||
|
||||
def restore_config (self):
|
||||
"""Restore config from backup."""
|
||||
for key in self.config_backup:
|
||||
confvalue = self.config_backup[key]
|
||||
if isinstance(confvalue, list):
|
||||
# make copy of lists to avoid unwanted inserted items
|
||||
confvalue = confvalue[:]
|
||||
self.config[key] = confvalue
|
||||
|
||||
def get_status (self):
|
||||
"""Return current application status."""
|
||||
return self._status
|
||||
|
||||
def set_status (self, status):
|
||||
"""Set application status."""
|
||||
self._status = status
|
||||
if status == Status.idle:
|
||||
self.aggregate = None
|
||||
self.controlButton.setText(_("Start"))
|
||||
self.controlButton.setIcon(self.icon_start)
|
||||
self.controlButton.setEnabled(True)
|
||||
self.actionSave.setEnabled(True)
|
||||
self.actionDebug.setEnabled(self.options.get_options()["debug"])
|
||||
self.treeView.sortByColumn(0, QtCore.Qt.AscendingOrder)
|
||||
self.treeView.setSortingEnabled(True)
|
||||
self.treeView.scrollToTop()
|
||||
self.movie.stop()
|
||||
# Reset progress information.
|
||||
self.label_active.setText(u"0")
|
||||
self.label_queued.setText(u"0")
|
||||
self.label_checked.setText(u"0")
|
||||
self.label_busy.hide()
|
||||
self.menubar.setEnabled(True)
|
||||
self.urlinput.setEnabled(True)
|
||||
self.restore_config()
|
||||
elif status == Status.checking:
|
||||
self.treeView.setSortingEnabled(False)
|
||||
self.debug.reset()
|
||||
self.set_statusmsg(_(u"Checking site..."))
|
||||
# disable commands
|
||||
self.menubar.setEnabled(False)
|
||||
self.urlinput.setEnabled(False)
|
||||
# reset widgets
|
||||
self.controlButton.setText(_("Stop"))
|
||||
self.controlButton.setIcon(self.icon_stop)
|
||||
self.controlButton.clicked.connect(self.checker.cancel)
|
||||
self.movie.start()
|
||||
self.label_busy.show()
|
||||
|
||||
status = property(get_status, set_status)
|
||||
|
||||
@QtCore.pyqtSlot()
|
||||
def on_actionHelp_triggered (self):
|
||||
"""Show help page."""
|
||||
url = QtCore.QUrl("%sindex.html" % DocBaseUrl)
|
||||
self.assistant.showDocumentation(url)
|
||||
|
||||
@QtCore.pyqtSlot()
|
||||
def on_actionOptions_triggered (self):
|
||||
"""Show option dialog."""
|
||||
self.options.exec_()
|
||||
|
||||
@QtCore.pyqtSlot()
|
||||
def on_actionQuit_triggered (self):
|
||||
"""Quit application."""
|
||||
self.close()
|
||||
|
||||
def closeEvent (self, e=None):
|
||||
"""Save settings and remove registered logging handler"""
|
||||
self.settings.save_geometry(dict(size=self.size(), pos=self.pos()))
|
||||
self.settings.save_treeviewcols(self.get_treeviewcols())
|
||||
self.settings.save_options(self.options.get_options())
|
||||
self.settings.save_recent_documents(self.recent.get_documents())
|
||||
self.settings.save_misc(dict(saveresultas=self.saveresultas))
|
||||
self.settings.sync()
|
||||
logconf.remove_loghandler(self.handler)
|
||||
if e is not None:
|
||||
e.accept()
|
||||
|
||||
@QtCore.pyqtSlot()
|
||||
def on_actionAbout_triggered (self):
|
||||
"""Display about dialog."""
|
||||
modules = u"<br>\n".join(configuration.get_modules_info())
|
||||
d = {
|
||||
"app": configuration.App,
|
||||
"appname": configuration.AppName,
|
||||
"copyright": configuration.HtmlCopyright,
|
||||
"donateurl": configuration.DonateUrl,
|
||||
"pyver": u"%d.%d.%d" % sys.version_info[:3],
|
||||
"modules": modules,
|
||||
"portable": _("yes") if configuration.Portable else _("no"),
|
||||
"releasedate": configuration.ReleaseDate,
|
||||
}
|
||||
QtGui.QMessageBox.about(self, _(u"About %(appname)s") % d,
|
||||
_(u"""<qt><center>
|
||||
<h1>%(app)s</h1>
|
||||
<p>Released on %(releasedate)s
|
||||
<p>Python: %(pyver)s<br>
|
||||
%(modules)s<br>
|
||||
Portable version: %(portable)s
|
||||
<p>%(copyright)s
|
||||
<br>%(appname)s is licensed under the
|
||||
<a href="http://www.gnu.org/licenses/gpl.html">GPL</a>
|
||||
Version 2 or later.
|
||||
<p>If you like %(appname)s, consider one of several ways to
|
||||
<a href="%(donateurl)s">donate</a>. Thanks!
|
||||
</center></qt>""") % d)
|
||||
|
||||
@QtCore.pyqtSlot()
|
||||
def on_actionDebug_triggered (self):
|
||||
"""Display debug dialog."""
|
||||
self.debug.show()
|
||||
|
||||
@QtCore.pyqtSlot()
|
||||
def on_actionOpen_project_triggered (self):
|
||||
"""Open project."""
|
||||
openproject(self)
|
||||
|
||||
@QtCore.pyqtSlot()
|
||||
def on_actionSave_project_triggered (self):
|
||||
"""Save project."""
|
||||
saveproject(self, self.get_url())
|
||||
|
||||
@QtCore.pyqtSlot()
|
||||
def on_actionSave_triggered (self):
|
||||
"""Save URL results."""
|
||||
saveresultas = urlsave(self, self.config, self.model.urls)
|
||||
if saveresultas:
|
||||
self.saveresultas = saveresultas
|
||||
|
||||
@QtCore.pyqtSlot()
|
||||
def on_actionCheckUpdates_triggered (self):
|
||||
"""Display update check result."""
|
||||
dialog = UpdateDialog(self)
|
||||
dialog.reset()
|
||||
dialog.show()
|
||||
|
||||
def start (self):
|
||||
"""Start a new check."""
|
||||
if self.status == Status.idle:
|
||||
self.check()
|
||||
|
||||
on_urlinput_returnPressed = start
|
||||
|
||||
def cancel (self):
|
||||
"""Note that checking is canceled."""
|
||||
self.controlButton.setEnabled(False)
|
||||
duration = strformat.strduration_long(self.config["aborttimeout"])
|
||||
self.set_statusmsg(_(u"Closing active URLs with timeout %s...") % duration)
|
||||
|
||||
@QtCore.pyqtSlot()
|
||||
def on_controlButton_clicked (self):
|
||||
"""Start or Cancel has been clicked."""
|
||||
if self.status == Status.idle:
|
||||
self.start()
|
||||
elif self.status == Status.checking:
|
||||
self.cancel()
|
||||
else:
|
||||
raise ValueError("Invalid application status %r" % self.status)
|
||||
|
||||
def get_url (self):
|
||||
"""Return URL to check from the urlinput widget."""
|
||||
url = strformat.stripurl(unicode(self.urlinput.text()))
|
||||
url = checker.guess_url(url)
|
||||
if url and u":" not in url:
|
||||
# Look for local file, else assume it's an HTTP URL.
|
||||
if not os.path.exists(url):
|
||||
url = u"http://%s" % url
|
||||
return url
|
||||
|
||||
def check (self):
|
||||
"""Check given URL."""
|
||||
self.model.clear()
|
||||
clear_properties(self)
|
||||
clear_statistics(self)
|
||||
self.set_config()
|
||||
aggregate = director.get_aggregate(self.config)
|
||||
url = self.get_url()
|
||||
if not url:
|
||||
self.set_statusmsg(_("Error, empty URL"))
|
||||
return
|
||||
self.set_statusmsg(_("Checking '%s'.") % strformat.limit(url, 40))
|
||||
url_data = checker.get_url_from(url, 0, aggregate, extern=(0, 0))
|
||||
self.recent.add_document(url)
|
||||
aggregate.urlqueue.put(url_data)
|
||||
self.aggregate = aggregate
|
||||
# check in background
|
||||
self.checker.check(self.aggregate)
|
||||
self.status = Status.checking
|
||||
|
||||
def set_properties (self, selected, deselected):
|
||||
"""Set URL properties for selected item."""
|
||||
indexes = selected.indexes()
|
||||
if len(indexes):
|
||||
index = indexes[0]
|
||||
urlitem = self.model.getUrlItem(index)
|
||||
if urlitem is not None:
|
||||
set_properties(self, urlitem.url_data)
|
||||
selected_rows = len(self.treeView.selectionModel().selectedRows())
|
||||
if selected_rows:
|
||||
self.set_statusmsg(_n("%d URL selected.", "%d URLs selected",
|
||||
selected_rows) % selected_rows)
|
||||
else:
|
||||
self.set_statusmsg(_("Ready."))
|
||||
|
||||
def on_treeView_customContextMenuRequested (self, point):
|
||||
"""Show item context menu."""
|
||||
urlitem = self.model.getUrlItem(self.treeView.currentIndex())
|
||||
if urlitem is not None:
|
||||
self.contextmenu.enableFromItem(urlitem)
|
||||
self.contextmenu.popup(QtGui.QCursor.pos())
|
||||
|
||||
@QtCore.pyqtSlot()
|
||||
def on_actionViewOnline_triggered (self):
|
||||
"""View item URL online."""
|
||||
urlitem = self.model.getUrlItem(self.treeView.currentIndex())
|
||||
if urlitem is not None:
|
||||
webbrowser.open(urlitem.url_data.url)
|
||||
|
||||
@QtCore.pyqtSlot()
|
||||
def on_actionViewParentOnline_triggered (self):
|
||||
"""View item parent URL online."""
|
||||
urlitem = self.model.getUrlItem(self.treeView.currentIndex())
|
||||
if urlitem is not None:
|
||||
webbrowser.open(urlitem.url_data.parent_url)
|
||||
|
||||
@QtCore.pyqtSlot()
|
||||
def on_actionViewParentSource_triggered (self):
|
||||
"""View item parent URL source in local text editor (read-only)."""
|
||||
urlitem = self.model.getUrlItem(self.treeView.currentIndex())
|
||||
if urlitem is not None:
|
||||
self.view_source(urlitem.url_data.parent_url,
|
||||
urlitem.url_data.line, urlitem.url_data.column)
|
||||
|
||||
def view_source (self, url, line, col):
|
||||
"""View URL source in editor window."""
|
||||
self.editor.setWindowTitle(u"View %s" % url)
|
||||
self.editor.setUrl(url)
|
||||
data, info = urlutil.get_content(url, proxy=self.config["proxy"])
|
||||
if data is None:
|
||||
msg = u"An error occurred retreiving URL `%s': %s." % (url, info)
|
||||
self.editor.setText(msg)
|
||||
else:
|
||||
content_type = httputil.get_content_type(info)
|
||||
if not content_type:
|
||||
# read function for content type guessing
|
||||
read = lambda: data
|
||||
content_type = mimeutil.guess_mimetype(url, read=read)
|
||||
self.editor.setContentType(content_type)
|
||||
self.editor.setText(data, line=line, col=col)
|
||||
self.editor.show()
|
||||
|
||||
@QtCore.pyqtSlot()
|
||||
def on_actionCopyToClipboard_triggered (self):
|
||||
"""Copy item URL to clipboard."""
|
||||
urlitem = self.model.getUrlItem(self.treeView.currentIndex())
|
||||
if urlitem:
|
||||
clipboard = QtGui.QApplication.clipboard()
|
||||
clipboard.setText(urlitem.url_data.url)
|
||||
event = QtCore.QEvent(QtCore.QEvent.Clipboard)
|
||||
QtGui.QApplication.sendEvent(clipboard, event)
|
||||
|
||||
def set_statusmsg (self, msg):
|
||||
"""Show given status message."""
|
||||
self.statusBar.showMessage(msg)
|
||||
if len(msg) > MaxMessageLength:
|
||||
self.label_status.setToolTip(msg)
|
||||
msg = msg[:MaxMessageLength-3]+u"..."
|
||||
else:
|
||||
self.label_status.setToolTip(u"")
|
||||
self.label_status.setText(msg)
|
||||
|
||||
def hover_link (self, link):
|
||||
"""Show given link in status bar."""
|
||||
self.statusBar.showMessage(link)
|
||||
|
||||
def log_status (self, checked, in_progress, queued, duration, num_urls):
|
||||
"""Update number of checked, active and queued links."""
|
||||
self.label_checked.setText(u"%d" % checked)
|
||||
self.label_active.setText(u"%d" % in_progress)
|
||||
self.label_queued.setText(u"%d" % queued)
|
||||
|
||||
def log_stats (self, statistics):
|
||||
"""Set statistic information for selected URL."""
|
||||
set_statistics(self, statistics)
|
||||
|
||||
def internal_error (self, msg):
|
||||
"""Display internal error message. Triggered by sys.excepthook()."""
|
||||
QtGui.QMessageBox.warning(self, _(u"LinkChecker internal error"), msg)
|
||||
|
||||
def handleDragEvent(self, event):
|
||||
"""Handle drag enter of move event."""
|
||||
mime = event.mimeData()
|
||||
if not mime.hasUrls():
|
||||
return event.ignore()
|
||||
url = mime.urls()[0]
|
||||
if url.scheme() != 'file':
|
||||
return event.ignore()
|
||||
event.accept()
|
||||
|
||||
def handleDropEvent(self, event):
|
||||
"""Handle drop event. Detects and loads project files, else sets the URL."""
|
||||
mime = event.mimeData()
|
||||
url = mime.urls()[0]
|
||||
if url.path().toLower().endsWith(ProjectExt):
|
||||
filename = unicode(url.toLocalFile())
|
||||
loadproject(self, filename)
|
||||
else:
|
||||
self.urlinput.setText(url.toString())
|
||||
|
||||
def retranslateUi(self, Window):
|
||||
"""Translate menu titles."""
|
||||
super(LinkCheckerMain, self).retranslateUi(Window)
|
||||
# self.menu_lang is created after calling retranslateUi
|
||||
# the first time, so check for its excistance
|
||||
if hasattr(self, "menu_lang"):
|
||||
self.menuLang.setTitle(_("&Language"))
|
||||
|
||||
def switch_language(self, action):
|
||||
"""Change UI language."""
|
||||
lang = str(action.data().toString())
|
||||
i18n.install_language(lang)
|
||||
self.retranslateUi(self)
|
||||
self.options.retranslateUi(self.options)
|
||||
self.debug.retranslateUi(self.debug)
|
||||
self.editor.retranslateUi(self.editor)
|
||||
|
|
@ -1,45 +0,0 @@
|
|||
# -*- coding: iso-8859-1 -*-
|
||||
# Copyright (C) 2008-2014 Bastian Kleineidam
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along
|
||||
# with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
from PyQt4 import QtCore
|
||||
from .. import director
|
||||
|
||||
|
||||
class CheckerThread (QtCore.QThread):
|
||||
"""Separate checker thread."""
|
||||
|
||||
def __init__ (self, parent=None):
|
||||
"""Reset check variables."""
|
||||
super(CheckerThread, self).__init__(parent)
|
||||
self.aggregate = None
|
||||
|
||||
def check (self, aggregate):
|
||||
"""Set check variables and start the thread."""
|
||||
self.aggregate = aggregate
|
||||
# setup the thread and call run()
|
||||
self.start()
|
||||
|
||||
def cancel (self):
|
||||
"""Reset check variables and set stop flag."""
|
||||
if self.aggregate is not None:
|
||||
aggregate = self.aggregate
|
||||
self.aggregate = None
|
||||
aggregate.cancel()
|
||||
|
||||
def run (self):
|
||||
"""Start checking."""
|
||||
assert self.aggregate.config["threads"] > 0
|
||||
director.check_urls(self.aggregate)
|
||||
|
|
@ -1,65 +0,0 @@
|
|||
# -*- coding: iso-8859-1 -*-
|
||||
# Copyright (C) 2009-2014 Bastian Kleineidam
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along
|
||||
# with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
from PyQt4 import QtGui
|
||||
import os
|
||||
try:
|
||||
import urlparse
|
||||
except ImportError:
|
||||
# Python 3
|
||||
from urllib import parse as urlparse
|
||||
from linkcheck.checker.fileurl import get_os_filename
|
||||
|
||||
class ContextMenu (QtGui.QMenu):
|
||||
"""Show context menu."""
|
||||
|
||||
def __init__ (self, parent=None):
|
||||
"""Add actions to context menu."""
|
||||
super(ContextMenu, self).__init__(parent)
|
||||
self.addAction(parent.actionViewOnline)
|
||||
self.addAction(parent.actionCopyToClipboard)
|
||||
self.addAction(parent.actionViewParentOnline)
|
||||
self.addAction(parent.actionViewParentSource)
|
||||
|
||||
def enableFromItem (self, item):
|
||||
"""Enable context menu actions depending on the item content."""
|
||||
parent = self.parentWidget()
|
||||
# data is an instance of CompactUrlData
|
||||
data = item.url_data
|
||||
# enable view online actions
|
||||
parent.actionViewOnline.setEnabled(bool(data.url))
|
||||
parent.actionViewParentOnline.setEnabled(bool(data.parent_url))
|
||||
# enable view source actions
|
||||
enable_parent_url_source = self.can_view_parent_source(data)
|
||||
parent.actionViewParentSource.setEnabled(enable_parent_url_source)
|
||||
|
||||
def can_view_parent_source (self, url_data):
|
||||
"""Determine if parent URL source can be retrieved."""
|
||||
if not url_data.valid:
|
||||
return False
|
||||
parent = url_data.parent_url
|
||||
if not parent:
|
||||
return False
|
||||
# Directory contents are dynamically generated, so it makes
|
||||
# no sense in viewing/editing them.
|
||||
if parent.startswith(u"file:"):
|
||||
path = urlparse.urlsplit(parent)[2]
|
||||
return not os.path.isdir(get_os_filename(path))
|
||||
if parent.startswith((u"ftp:", u"ftps:")):
|
||||
path = urlparse.urlsplit(parent)[2]
|
||||
return bool(path) and not path.endswith(u'/')
|
||||
# Only HTTP left
|
||||
return parent.startswith((u"http:", u"https:"))
|
||||
|
|
@ -1,43 +0,0 @@
|
|||
# -*- coding: iso-8859-1 -*-
|
||||
# Copyright (C) 2009-2014 Bastian Kleineidam
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along
|
||||
# with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
from PyQt4 import QtCore, QtGui
|
||||
from .linkchecker_ui_debug import Ui_DebugDialog
|
||||
|
||||
|
||||
class LinkCheckerDebug (QtGui.QDialog, Ui_DebugDialog):
|
||||
"""Show debug text."""
|
||||
|
||||
log_msg_signal = QtCore.pyqtSignal(str)
|
||||
|
||||
def __init__ (self, parent=None):
|
||||
"""Setup the debug message dialog."""
|
||||
super(LinkCheckerDebug, self).__init__(parent)
|
||||
self.setupUi(self)
|
||||
font = QtGui.QFont("Consolas", 11)
|
||||
font.setFixedPitch(True)
|
||||
self.textEdit.document().setDefaultFont(font)
|
||||
self.log_msg_signal.connect(self.textEdit.appendPlainText)
|
||||
self.reset()
|
||||
|
||||
def reset (self):
|
||||
"""Clear all debug info."""
|
||||
self.textEdit.clear()
|
||||
|
||||
def getText (self):
|
||||
"""Get debug info as string."""
|
||||
return self.textEdit.toPlainText()
|
||||
|
|
@ -1,185 +0,0 @@
|
|||
# -*- coding: iso-8859-1 -*-
|
||||
# Copyright (C) 2010-2014 Bastian Kleineidam
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along
|
||||
# with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
import os
|
||||
try:
|
||||
import urlparse
|
||||
except ImportError:
|
||||
# Python 3
|
||||
from urllib import parse as urlparse
|
||||
from PyQt4 import QtGui, QtCore
|
||||
from .linkchecker_ui_editor import Ui_EditorDialog
|
||||
from ..checker.fileurl import get_os_filename
|
||||
try:
|
||||
from .editor_qsci import ContentTypeLexers, Editor
|
||||
except ImportError:
|
||||
from .editor_qt import ContentTypeLexers, Editor
|
||||
|
||||
class EditorWindow (QtGui.QDialog, Ui_EditorDialog):
|
||||
"""Editor window."""
|
||||
|
||||
# emitted after successful save
|
||||
saved = QtCore.pyqtSignal(str)
|
||||
# emitted after successful load
|
||||
loaded = QtCore.pyqtSignal(str)
|
||||
|
||||
def __init__ (self, parent=None):
|
||||
"""Initialize the editor widget."""
|
||||
super(EditorWindow, self).__init__(parent)
|
||||
self.setupUi(self)
|
||||
# filename used for saving
|
||||
self.filename = None
|
||||
# the Scintilla editor widget
|
||||
self.editor = Editor(parent=self.frame)
|
||||
layout = QtGui.QVBoxLayout(self.frame)
|
||||
layout.setContentsMargins(0, 0, 0, 0)
|
||||
layout.addWidget(self.editor)
|
||||
# for debugging
|
||||
#self.setText(("1234567890"*8) + "\n<html><head>\n<title>x</title>\n</head>\n")
|
||||
#lexer = Qsci.QsciLexerHTML()
|
||||
#lexer.setFont(self.editor.font())
|
||||
#self.editor.setLexer(lexer)
|
||||
#self.editor.setCursorPosition(1, 1)
|
||||
#self.show()
|
||||
|
||||
def setContentType (self, content_type):
|
||||
"""Choose a lexer according to given content type."""
|
||||
lexerclass = ContentTypeLexers.get(content_type.lower())
|
||||
self.editor.highlight(lexerclass)
|
||||
|
||||
def setText (self, text, line=1, col=1):
|
||||
"""Set editor text and jump to given line and column."""
|
||||
self.editor.setText(text)
|
||||
self.editor.setCursorPosition(line-1, col-1)
|
||||
self.editor.setModified(False)
|
||||
|
||||
def setUrl (self, url):
|
||||
"""If URL is a file:// URL, store the filename of it as base
|
||||
directory for the "save as" dialog."""
|
||||
self.basedir = ""
|
||||
if url and url.startswith("file://"):
|
||||
urlparts = urlparse.urlsplit(url)
|
||||
path = get_os_filename(urlparts[2])
|
||||
if os.path.exists(path):
|
||||
self.basedir = path
|
||||
|
||||
@QtCore.pyqtSlot()
|
||||
def on_actionSave_triggered (self):
|
||||
"""Save changed editor contents."""
|
||||
if self.editor.isModified() or not self.filename:
|
||||
self.save()
|
||||
|
||||
def closeEvent (self, e=None):
|
||||
"""Save settings and remove registered logging handler"""
|
||||
if self.editor.isModified():
|
||||
# ask if user wants to save
|
||||
if self.wants_save():
|
||||
if self.save():
|
||||
e.accept()
|
||||
else:
|
||||
# saving error or user canceled
|
||||
e.ignore()
|
||||
else:
|
||||
# discard changes
|
||||
e.accept()
|
||||
else:
|
||||
# unchanged
|
||||
e.accept()
|
||||
|
||||
def wants_save (self):
|
||||
"""Ask user if he wants to save changes. Return True if user
|
||||
wants to save, else False."""
|
||||
dialog = QtGui.QMessageBox(parent=self)
|
||||
dialog.setIcon(QtGui.QMessageBox.Question)
|
||||
dialog.setWindowTitle(_("Save file?"))
|
||||
dialog.setText(_("The document has been modified."))
|
||||
dialog.setInformativeText(_("Do you want to save your changes?"))
|
||||
dialog.setStandardButtons(QtGui.QMessageBox.Save |
|
||||
QtGui.QMessageBox.Discard)
|
||||
dialog.setDefaultButton(QtGui.QMessageBox.Save)
|
||||
return dialog.exec_() == QtGui.QMessageBox.Save
|
||||
|
||||
def save (self):
|
||||
"""Save editor contents to file."""
|
||||
if not self.filename:
|
||||
title = _("Save File As")
|
||||
res = QtGui.QFileDialog.getSaveFileName(self, title, self.basedir)
|
||||
if not res:
|
||||
# user canceled
|
||||
return
|
||||
self.filename = res
|
||||
self.setWindowTitle(self.filename)
|
||||
else:
|
||||
if not os.path.isfile(self.filename):
|
||||
return
|
||||
if not os.access(self.filename, os.W_OK):
|
||||
return
|
||||
fh = None
|
||||
saved = False
|
||||
try:
|
||||
try:
|
||||
fh = QtCore.QFile(self.filename)
|
||||
if not fh.open(QtCore.QIODevice.WriteOnly):
|
||||
raise IOError(fh.errorString())
|
||||
stream = QtCore.QTextStream(fh)
|
||||
stream.setCodec("UTF-8")
|
||||
stream << self.editor.text()
|
||||
self.editor.setModified(False)
|
||||
saved = True
|
||||
except (IOError, OSError) as e:
|
||||
err = QtGui.QMessageBox(self)
|
||||
err.setText(str(e))
|
||||
err.exec_()
|
||||
finally:
|
||||
if fh is not None:
|
||||
fh.close()
|
||||
if saved:
|
||||
self.saved.emit(self.filename)
|
||||
return saved
|
||||
|
||||
def load (self, filename):
|
||||
"""Load editor contents from file."""
|
||||
if not os.path.isfile(filename):
|
||||
return
|
||||
if not os.access(filename, os.R_OK):
|
||||
return
|
||||
self.filename = filename
|
||||
if not os.access(filename, os.W_OK):
|
||||
title = u"%s (%s)" % (self.filename, _(u"readonly"))
|
||||
else:
|
||||
title = self.filename
|
||||
self.setWindowTitle(title)
|
||||
fh = None
|
||||
loaded = False
|
||||
try:
|
||||
try:
|
||||
fh = QtCore.QFile(self.filename)
|
||||
if not fh.open(QtCore.QIODevice.ReadOnly):
|
||||
raise IOError(fh.errorString())
|
||||
stream = QtCore.QTextStream(fh)
|
||||
stream.setCodec("UTF-8")
|
||||
self.setText(stream.readAll())
|
||||
loaded = True
|
||||
except (IOError, OSError) as e:
|
||||
err = QtGui.QMessageBox(self)
|
||||
err.setText(str(e))
|
||||
err.exec_()
|
||||
finally:
|
||||
if fh is not None:
|
||||
fh.close()
|
||||
if loaded:
|
||||
self.loaded.emit(self.filename)
|
||||
|
|
@ -1,109 +0,0 @@
|
|||
# -*- coding: iso-8859-1 -*-
|
||||
# Copyright (C) 2011-2014 Bastian Kleineidam
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along
|
||||
# with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
"""
|
||||
Text editor implemented with QScintilla
|
||||
"""
|
||||
from PyQt4 import QtGui, Qsci
|
||||
|
||||
# Map MIME type to Scintilla lexer class
|
||||
ContentTypeLexers = {
|
||||
"application/x-shellscript": Qsci.QsciLexerBash,
|
||||
"application/x-sh": Qsci.QsciLexerBash,
|
||||
"application/x-msdos-program": Qsci.QsciLexerBatch,
|
||||
#"": Qsci.QsciLexerCMake,
|
||||
"text/x-c++src": Qsci.QsciLexerCPP,
|
||||
"text/css": Qsci.QsciLexerCSS,
|
||||
#"": Qsci.QsciLexerCSharp,
|
||||
#"": Qsci.QsciLexerCustom,
|
||||
"text/x-dsrc": Qsci.QsciLexerD,
|
||||
"text/x-diff": Qsci.QsciLexerDiff,
|
||||
#"": Qsci.QsciLexerFortran,
|
||||
#"": Qsci.QsciLexerFortran77,
|
||||
"text/html": Qsci.QsciLexerHTML,
|
||||
#"": Qsci.QsciLexerIDL,
|
||||
"text/x-java": Qsci.QsciLexerJava,
|
||||
"application/javascript": Qsci.QsciLexerJavaScript,
|
||||
#"": Qsci.QsciLexerLua,
|
||||
"text/x-makefile": Qsci.QsciLexerMakefile,
|
||||
#"": Qsci.QsciLexerPOV,
|
||||
"text/x-pascal": Qsci.QsciLexerPascal,
|
||||
"text/x-perl": Qsci.QsciLexerPerl,
|
||||
"application/postscript": Qsci.QsciLexerPostScript,
|
||||
"text/plain+ini": Qsci.QsciLexerProperties,
|
||||
"text/x-python": Qsci.QsciLexerPython,
|
||||
"application/x-ruby": Qsci.QsciLexerRuby,
|
||||
#"": Qsci.QsciLexerSQL,
|
||||
#"": Qsci.QsciLexerSpice,
|
||||
"application/x-tcl": Qsci.QsciLexerTCL,
|
||||
"application/x-latex": Qsci.QsciLexerTeX,
|
||||
#"": Qsci.QsciLexerVHDL,
|
||||
#"": Qsci.QsciLexerVerilog,
|
||||
"application/xml": Qsci.QsciLexerXML,
|
||||
#"": Qsci.QsciLexerYAML,
|
||||
}
|
||||
|
||||
class Editor (Qsci.QsciScintilla):
|
||||
"""Configured QsciScintilla widget."""
|
||||
|
||||
def __init__ (self, parent=None):
|
||||
"""Set Scintilla options for font, colors, etc."""
|
||||
super(Editor, self).__init__(parent)
|
||||
# Use Courier font with fixed width
|
||||
font = QtGui.QFont("Consolas", 11)
|
||||
font.setFixedPitch(True)
|
||||
|
||||
# Set the default font of the editor
|
||||
# and take the same font for line numbers
|
||||
self.setFont(font)
|
||||
self.setMarginsFont(font)
|
||||
|
||||
# line number margin for 4 digits (plus 2px extra space)
|
||||
margin = QtGui.QFontMetrics(font).width("0"*4)+2
|
||||
# Display line numbers, margin 0 is for line numbers
|
||||
self.setMarginWidth(0, margin)
|
||||
self.setMarginLineNumbers(0, True)
|
||||
|
||||
# Show whitespace to help detect whitespace errors
|
||||
self.setWhitespaceVisibility(True)
|
||||
|
||||
# Use boxes as folding visual
|
||||
self.setFolding(self.BoxedTreeFoldStyle)
|
||||
|
||||
# Braces matching
|
||||
self.setBraceMatching(self.SloppyBraceMatch)
|
||||
|
||||
# Editing line color
|
||||
self.setCaretLineVisible(True)
|
||||
self.setCaretLineBackgroundColor(QtGui.QColor("#e5e5cb"))
|
||||
|
||||
# line numbers margin colors
|
||||
self.setMarginsBackgroundColor(QtGui.QColor("#e5e5e5"))
|
||||
self.setMarginsForegroundColor(QtGui.QColor("#333333"))
|
||||
|
||||
# folding margin colors (foreground,background)
|
||||
self.setFoldMarginColors(QtGui.QColor("#f5f5dc"),
|
||||
QtGui.QColor("#aaaaaa"))
|
||||
|
||||
def highlight (self, lexerclass):
|
||||
"""Set syntax highlighter."""
|
||||
if lexerclass:
|
||||
lexer = lexerclass()
|
||||
lexer.setFont(self.font())
|
||||
self.setLexer(lexer)
|
||||
else:
|
||||
# use no styling
|
||||
self.setLexer()
|
||||
|
|
@ -1,152 +0,0 @@
|
|||
# -*- coding: iso-8859-1 -*-
|
||||
# Copyright (C) 2011-2014 Bastian Kleineidam
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along
|
||||
# with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
"""
|
||||
Text editor implemented with Qt
|
||||
"""
|
||||
from PyQt4 import QtGui, QtCore
|
||||
from . import syntax
|
||||
|
||||
# Map MIME type to QSyntaxHighlighter class
|
||||
ContentTypeLexers = {
|
||||
"text/html": syntax.HtmlHighlighter,
|
||||
"application/xml": syntax.XmlHighlighter,
|
||||
"text/plain+ini": syntax.IniHighlighter,
|
||||
}
|
||||
|
||||
class LineNumberArea (QtGui.QWidget):
|
||||
"""Display line numbers."""
|
||||
|
||||
def sizeHint (self):
|
||||
"""Return calculated width for line number area."""
|
||||
return QtCore.QSize(self.parentWidget().lineNumberAreaWidth(), 0)
|
||||
|
||||
def paintEvent (self, event):
|
||||
"""Call paint method of parent widget."""
|
||||
self.parentWidget().lineNumberAreaPaintEvent(event)
|
||||
|
||||
|
||||
class Editor (QtGui.QPlainTextEdit):
|
||||
"""Qt editor with line numbering."""
|
||||
|
||||
def __init__ (self, parent):
|
||||
"""Initialize line numbering."""
|
||||
super(Editor, self).__init__(parent)
|
||||
font = QtGui.QFont("Consolas", 11)
|
||||
font.setFixedPitch(True)
|
||||
self.document().setDefaultFont(font)
|
||||
self.lineNumberArea = LineNumberArea(self)
|
||||
self.blockCountChanged.connect(self.updateLineNumberAreaWidth)
|
||||
self.updateRequest.connect(self.updateLineNumberArea)
|
||||
self.cursorPositionChanged.connect(self.highlightCurrentLine)
|
||||
self.updateLineNumberAreaWidth(0)
|
||||
self.highlightCurrentLine()
|
||||
|
||||
def highlight (self, lexerclass):
|
||||
"""Set syntax highlighter."""
|
||||
if lexerclass:
|
||||
self.lexer = lexerclass(self.document())
|
||||
else:
|
||||
self.lexer = None
|
||||
|
||||
def setText (self, text):
|
||||
"""Set editor text."""
|
||||
return self.setPlainText(text)
|
||||
|
||||
def text (self):
|
||||
"""Return editor text."""
|
||||
return self.toPlainText()
|
||||
|
||||
def setModified (self, flag):
|
||||
"""Set modified flag of underlying document."""
|
||||
return self.document().setModified(flag)
|
||||
|
||||
def isModified (self):
|
||||
"""Return modified flag of underlying document."""
|
||||
return self.document().isModified()
|
||||
|
||||
def setCursorPosition (self, line, column=0):
|
||||
"""Move cursor to given line and column. Line counting starts
|
||||
with zero."""
|
||||
block = self.document().findBlockByNumber(line)
|
||||
if block.isValid():
|
||||
cursor = QtGui.QTextCursor(block)
|
||||
if column > 0:
|
||||
cursor.movePosition(QtGui.QTextCursor.Right,
|
||||
QtGui.QTextCursor.MoveAnchor, column)
|
||||
self.setTextCursor(cursor)
|
||||
self.centerCursor()
|
||||
|
||||
def lineNumberAreaPaintEvent (self, event):
|
||||
"""Paint line numbers."""
|
||||
painter = QtGui.QPainter(self.lineNumberArea)
|
||||
painter.fillRect(event.rect(), QtCore.Qt.lightGray)
|
||||
block = self.firstVisibleBlock()
|
||||
blockNumber = block.blockNumber()
|
||||
top = self.blockBoundingGeometry(block).translated(self.contentOffset()).top()
|
||||
bottom = top + self.blockBoundingRect(block).height()
|
||||
while block.isValid() and top <= event.rect().bottom():
|
||||
if block.isVisible() and bottom >= event.rect().top():
|
||||
number = str(blockNumber + 1)
|
||||
painter.setPen(QtCore.Qt.black)
|
||||
painter.drawText(0, top, self.lineNumberArea.width(),
|
||||
self.fontMetrics().height(),
|
||||
QtCore.Qt.AlignRight, number)
|
||||
block = block.next()
|
||||
top = bottom
|
||||
bottom = top + self.blockBoundingRect(block).height()
|
||||
blockNumber += 1
|
||||
|
||||
def lineNumberAreaWidth (self):
|
||||
"""Calculate line number area width."""
|
||||
digits = max(1, len(str(self.blockCount())))
|
||||
onecharwidth = self.fontMetrics().width('9')
|
||||
space = 3 + onecharwidth * digits
|
||||
return space
|
||||
|
||||
def resizeEvent (self, event):
|
||||
"""Resize line number area together with editor."""
|
||||
super(Editor, self).resizeEvent(event)
|
||||
cr = self.contentsRect()
|
||||
self.lineNumberArea.setGeometry(QtCore.QRect(cr.left(), cr.top(),
|
||||
self.lineNumberAreaWidth(), cr.height()))
|
||||
|
||||
def updateLineNumberAreaWidth (self, newBlockCount):
|
||||
"""Update the line number area width."""
|
||||
self.setViewportMargins(self.lineNumberAreaWidth(), 0, 0, 0)
|
||||
|
||||
def highlightCurrentLine (self):
|
||||
"""Highlight the current line."""
|
||||
extraSelections = []
|
||||
if not self.isReadOnly():
|
||||
selection = QtGui.QTextEdit.ExtraSelection()
|
||||
lineColor = QtGui.QColor(QtCore.Qt.yellow).lighter(160)
|
||||
selection.format.setBackground(lineColor)
|
||||
selection.format.setProperty(QtGui.QTextFormat.FullWidthSelection, True)
|
||||
selection.cursor = self.textCursor()
|
||||
selection.cursor.clearSelection()
|
||||
extraSelections.append(selection)
|
||||
self.setExtraSelections(extraSelections)
|
||||
|
||||
def updateLineNumberArea (self, rect, dy):
|
||||
"""Update the line number area."""
|
||||
if dy:
|
||||
self.lineNumberArea.scroll(0, dy)
|
||||
else:
|
||||
self.lineNumberArea.update(0, rect.y(),
|
||||
self.lineNumberArea.width(), rect.height())
|
||||
if rect.contains(self.viewport().rect()):
|
||||
self.updateLineNumberAreaWidth(0)
|
||||
|
|
@ -1,77 +0,0 @@
|
|||
# -*- coding: iso-8859-1 -*-
|
||||
# Copyright (C) 2009-2014 Bastian Kleineidam
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along
|
||||
# with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
from .. import configuration
|
||||
from PyQt4 import QtCore, QtGui, QtHelp
|
||||
|
||||
|
||||
class HelpWindow (QtGui.QDialog):
|
||||
"""A custom help display dialog."""
|
||||
|
||||
def __init__ (self, parent, qhcpath):
|
||||
"""Initialize dialog and load qhc help project from given path."""
|
||||
super(HelpWindow, self).__init__(parent)
|
||||
self.engine = QtHelp.QHelpEngine(qhcpath, self)
|
||||
self.engine.setupData()
|
||||
self.setWindowTitle(u"%s Help" % configuration.AppName)
|
||||
self.build_ui()
|
||||
|
||||
def build_ui (self):
|
||||
"""Build UI for the help window."""
|
||||
splitter = QtGui.QSplitter()
|
||||
splitter.setOrientation(QtCore.Qt.Vertical)
|
||||
self.browser = HelpBrowser(splitter, self.engine)
|
||||
self.tree = self.engine.contentWidget()
|
||||
self.tree.setExpandsOnDoubleClick(False)
|
||||
self.tree.linkActivated.connect(self.browser.setSource)
|
||||
splitter.addWidget(self.tree)
|
||||
splitter.addWidget(self.browser)
|
||||
splitter.setSizes((70, 530))
|
||||
hlayout = QtGui.QHBoxLayout()
|
||||
hlayout.addWidget(splitter)
|
||||
self.setLayout(hlayout)
|
||||
self.resize(800, 600)
|
||||
|
||||
def showDocumentation (self, url):
|
||||
"""Show given URL in help browser."""
|
||||
self.tree.expandAll()
|
||||
self.browser.setSource(url)
|
||||
self.show()
|
||||
|
||||
|
||||
class HelpBrowser (QtGui.QTextBrowser):
|
||||
"""A QTextBrowser that can handle qthelp:// URLs."""
|
||||
|
||||
def __init__ (self, parent, engine):
|
||||
"""Initialize and store given HelpEngine instance."""
|
||||
super(HelpBrowser, self).__init__(parent)
|
||||
self.engine = engine
|
||||
|
||||
def setSource (self, url):
|
||||
"""Open HTTP URLs in external browser, else call base class
|
||||
implementation."""
|
||||
if url.scheme() == "http":
|
||||
import webbrowser
|
||||
webbrowser.open(str(url.toString()))
|
||||
else:
|
||||
QtGui.QTextBrowser.setSource(self, url)
|
||||
|
||||
def loadResource (self, rtype, url):
|
||||
"""Handle qthelp:// URLs, load content from help engine."""
|
||||
if url.scheme() == "qthelp":
|
||||
return QtCore.QVariant(self.engine.fileData(url))
|
||||
return QtGui.QTextBrowser.loadResource(self, rtype, url)
|
||||
|
|
@ -1,226 +0,0 @@
|
|||
# -*- coding: iso-8859-1 -*-
|
||||
# Copyright (C) 2010-2014 Bastian Kleineidam
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along
|
||||
# with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
from PyQt4 import QtCore, QtGui
|
||||
|
||||
class LineEdit (QtGui.QLineEdit):
|
||||
"""A line edit widget displaying a clear button if there is some text
|
||||
and a down-arrow button displaying a list of strings (eg. recent
|
||||
documents)."""
|
||||
|
||||
def __init__ (self, parent=None):
|
||||
"""Initialize buttons and size settings."""
|
||||
super(LineEdit, self).__init__(parent)
|
||||
self.listmodel = None
|
||||
self.listview = None
|
||||
self.setup_clear_button()
|
||||
self.setup_list_button()
|
||||
self.setup_size_metrics()
|
||||
|
||||
def setup_clear_button (self):
|
||||
"""Initialize the clear button."""
|
||||
self.clearButton = QtGui.QToolButton(self)
|
||||
pixmap = QtGui.QPixmap(":/icons/clear.png")
|
||||
self.clearButton.setIcon(QtGui.QIcon(pixmap))
|
||||
self.clearButton.setIconSize(pixmap.size())
|
||||
self.clearButton.setCursor(QtCore.Qt.ArrowCursor)
|
||||
style = "QToolButton { border: none; padding: 0px; }"
|
||||
self.clearButton.setStyleSheet(style)
|
||||
self.clearButton.hide()
|
||||
self.clearButton.clicked.connect(self.clear)
|
||||
self.textChanged.connect(self.updateCloseButton)
|
||||
|
||||
def setup_list_button (self):
|
||||
"""Initialize the dropdown list button."""
|
||||
self.listButton = QtGui.QToolButton(self)
|
||||
pixmap = QtGui.QPixmap(":/icons/arrow_down.png")
|
||||
self.listButton.setIcon(QtGui.QIcon(pixmap))
|
||||
self.listButton.setIconSize(pixmap.size())
|
||||
self.listButton.setCursor(QtCore.Qt.ArrowCursor)
|
||||
style = "QToolButton { border: none; padding: 0px; }"
|
||||
self.listButton.setStyleSheet(style)
|
||||
self.listButton.hide()
|
||||
self.listButton.clicked.connect(self.toggle_list)
|
||||
|
||||
def setModel (self, model):
|
||||
"""Set list model for list of recent documents."""
|
||||
self.listmodel = model
|
||||
self.listview = QtGui.QListView()
|
||||
self.listview.setModel(model)
|
||||
self.listview.setWindowFlags(QtCore.Qt.Popup)
|
||||
self.listview.setFocusPolicy(QtCore.Qt.NoFocus)
|
||||
self.listview.setFocusProxy(self)
|
||||
self.listview.setMouseTracking(True)
|
||||
self.listview.setUniformItemSizes(True)
|
||||
self.listview.setEditTriggers(QtGui.QAbstractItemView.NoEditTriggers)
|
||||
self.listview.setSelectionBehavior(QtGui.QAbstractItemView.SelectRows)
|
||||
self.listview.setFrameStyle(QtGui.QFrame.Box | QtGui.QFrame.Plain)
|
||||
self.listview.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
|
||||
self.listview.installEventFilter(self)
|
||||
self.listview.clicked.connect(self.selectRecentDocument)
|
||||
self.listview.hide()
|
||||
updatefunc = lambda parent, start, end: self.updateListButton
|
||||
self.listmodel.rowsInserted.connect(updatefunc)
|
||||
self.listmodel.rowsRemoved.connect(updatefunc)
|
||||
self.updateListButton()
|
||||
|
||||
def eventFilter(self, obj, event):
|
||||
"""Handle events from the listview popup."""
|
||||
if obj != self.listview:
|
||||
return False
|
||||
|
||||
if event.type() == QtCore.QEvent.MouseButtonPress:
|
||||
self.listview.hide()
|
||||
self.setFocus()
|
||||
return True
|
||||
|
||||
if event.type() == QtCore.QEvent.KeyPress:
|
||||
consumed = False
|
||||
key = event.key()
|
||||
if key in (QtCore.Qt.Key_Enter, QtCore.Qt.Key_Return):
|
||||
self.doneCompletion()
|
||||
consumed = True
|
||||
elif key == QtCore.Qt.Key_Escape:
|
||||
self.setFocus()
|
||||
self.listview.hide()
|
||||
consumed = True
|
||||
elif key in (QtCore.Qt.Key_Up, QtCore.Qt.Key_Down,
|
||||
QtCore.Qt.Key_Home, QtCore.Qt.Key_End,
|
||||
QtCore.Qt.Key_PageUp, QtCore.Qt.Key_PageDown):
|
||||
pass
|
||||
else:
|
||||
self.setFocus()
|
||||
self.event(event)
|
||||
self.listview.hide()
|
||||
return consumed
|
||||
return False
|
||||
|
||||
def selectRecentDocument (self, index):
|
||||
"""Select recent document text after click on the list view."""
|
||||
self.listview.hide()
|
||||
item = self.listmodel.data(index)
|
||||
text = unicode(item.toString())
|
||||
self.setText(text)
|
||||
|
||||
def setup_size_metrics (self):
|
||||
"""Set widget size including the buttons."""
|
||||
frameWidth = self.style().pixelMetric(QtGui.QStyle.PM_DefaultFrameWidth)
|
||||
padding_right = self.clearButton.sizeHint().width() + frameWidth + 1
|
||||
padding_left = self.listButton.sizeHint().width() + frameWidth + 1
|
||||
style = "QLineEdit { padding-left: %dpx; padding-right: %dpx } " % (
|
||||
padding_left, padding_right)
|
||||
self.setStyleSheet(style)
|
||||
# minimum width
|
||||
minSize = self.minimumSizeHint()
|
||||
buttonWidth = padding_left + padding_right
|
||||
minWidth = max(minSize.width(), buttonWidth)
|
||||
# minimum height
|
||||
buttonHeight = max(self.clearButton.sizeHint().height(),
|
||||
self.listButton.sizeHint().height())
|
||||
minHeight = max(minSize.height(), buttonHeight + frameWidth*2)
|
||||
# set minimum size
|
||||
self.setMinimumSize(minWidth, minHeight)
|
||||
|
||||
def resizeEvent (self, event):
|
||||
"""Move the buttons due to resize event."""
|
||||
frameWidth = self.style().pixelMetric(QtGui.QStyle.PM_DefaultFrameWidth)
|
||||
bottom = self.rect().y() + self.rect().height()
|
||||
# clear button
|
||||
sizeHint = self.clearButton.sizeHint()
|
||||
x = self.rect().right() - frameWidth - sizeHint.width()
|
||||
y = (bottom - sizeHint.height()) / 2
|
||||
self.clearButton.move(x,y)
|
||||
# list button
|
||||
sizeHint = self.listButton.sizeHint()
|
||||
# add one to x and y since the button icon is a little off
|
||||
x = self.rect().left() + frameWidth + 1
|
||||
y = (bottom - sizeHint.height()) / 2 + 1
|
||||
self.listButton.move(x,y)
|
||||
|
||||
def updateListButton (self):
|
||||
"""Show or hide button for list of documents."""
|
||||
self.listButton.setVisible(bool(self.listmodel.rowCount()))
|
||||
|
||||
def updateCloseButton (self, text):
|
||||
"""Only display the clear button if there is some text."""
|
||||
self.clearButton.setVisible(bool(text))
|
||||
|
||||
def toggle_list (self):
|
||||
"""Show or hide list of documents."""
|
||||
if self.listview.isHidden():
|
||||
self.listview.adjustSize()
|
||||
point = self.mapToGlobal(QtCore.QPoint(0, self.height()))
|
||||
self.listview.move(point)
|
||||
self.listview.setFocus()
|
||||
self.listview.show()
|
||||
else:
|
||||
self.listview.hide()
|
||||
|
||||
def addMenuEntries (self, menu):
|
||||
"""Add browser bookmark actions to menu."""
|
||||
name = _("Insert %(browser)s bookmark file")
|
||||
if find_firefox():
|
||||
action = menu.addAction(name % {"browser": u"Firefox"})
|
||||
action.triggered.connect(lambda: self.setText(find_firefox()))
|
||||
if find_chrome():
|
||||
action = menu.addAction(name % {"browser": u"Google Chrome"})
|
||||
action.triggered.connect(lambda: self.setText(find_chrome()))
|
||||
if find_chromium():
|
||||
action = menu.addAction(name % {"browser": u"Chromium"})
|
||||
action.triggered.connect(lambda: self.setText(find_chromium()))
|
||||
if find_opera():
|
||||
action = menu.addAction(name % {"browser": u"Opera"})
|
||||
action.triggered.connect(lambda: self.setText(find_opera()))
|
||||
if find_safari():
|
||||
action = menu.addAction(name % {"browser": u"Safari"})
|
||||
action.triggered.connect(lambda: self.setText(find_safari()))
|
||||
|
||||
def contextMenuEvent (self, event):
|
||||
"""Handle context menu event."""
|
||||
menu = self.createStandardContextMenu()
|
||||
self.addMenuEntries(menu)
|
||||
menu.exec_(event.globalPos())
|
||||
|
||||
|
||||
def find_firefox ():
|
||||
"""Return Firefox bookmark filename or empty string if not found."""
|
||||
from ..bookmarks.firefox import find_bookmark_file
|
||||
return find_bookmark_file()
|
||||
|
||||
|
||||
def find_chrome ():
|
||||
"""Return Google Chrome bookmark filename or empty string if not found."""
|
||||
from ..bookmarks.chrome import find_bookmark_file
|
||||
return find_bookmark_file()
|
||||
|
||||
|
||||
def find_chromium ():
|
||||
"""Return Chromium bookmark filename or empty string if not found."""
|
||||
from ..bookmarks.chromium import find_bookmark_file
|
||||
return find_bookmark_file()
|
||||
|
||||
|
||||
def find_opera ():
|
||||
"""Return Opera bookmark filename or empty string if not found."""
|
||||
from ..bookmarks.opera import find_bookmark_file
|
||||
return find_bookmark_file()
|
||||
|
||||
|
||||
def find_safari ():
|
||||
"""Return Safari bookmark filename or empty string if not found."""
|
||||
from ..bookmarks.safari import find_bookmark_file
|
||||
return find_bookmark_file()
|
||||
|
|
@ -1,882 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Resource object code
|
||||
#
|
||||
# Created: Wed May 11 00:26:36 2011
|
||||
# by: The Resource Compiler for PyQt (Qt v4.7.2)
|
||||
#
|
||||
# WARNING! All changes made in this file will be lost!
|
||||
|
||||
from PyQt4 import QtCore
|
||||
|
||||
qt_resource_data = "\
|
||||
\x00\x00\x01\xbc\
|
||||
\x89\
|
||||
\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\
|
||||
\x00\x00\x0c\x00\x00\x00\x0c\x08\x06\x00\x00\x00\x56\x75\x5c\xe7\
|
||||
\x00\x00\x00\x01\x73\x52\x47\x42\x00\xae\xce\x1c\xe9\x00\x00\x00\
|
||||
\x06\x62\x4b\x47\x44\x00\xff\x00\xff\x00\xff\xa0\xbd\xa7\x93\x00\
|
||||
\x00\x00\x09\x70\x48\x59\x73\x00\x00\x0d\x61\x00\x00\x0d\x3a\x01\
|
||||
\x65\x6b\xe6\xb1\x00\x00\x00\x07\x74\x49\x4d\x45\x07\xdb\x05\x0a\
|
||||
\x16\x19\x20\xab\xb5\x7f\x4a\x00\x00\x00\x19\x74\x45\x58\x74\x43\
|
||||
\x6f\x6d\x6d\x65\x6e\x74\x00\x43\x72\x65\x61\x74\x65\x64\x20\x77\
|
||||
\x69\x74\x68\x20\x47\x49\x4d\x50\x57\x81\x0e\x17\x00\x00\x01\x17\
|
||||
\x49\x44\x41\x54\x28\xcf\xad\x91\x3d\x4e\x02\x61\x14\x45\xcf\xc7\
|
||||
\x4c\xe5\x00\x56\xac\x00\x88\x83\x7b\x90\x15\xe0\x0e\xa4\x22\xa0\
|
||||
\xb4\x6a\x2b\x09\x84\x0e\x4c\x24\x91\x1e\x1b\xcc\xb0\x01\x0a\x4a\
|
||||
\x76\x41\x31\xb0\x00\xf9\x99\x38\x34\x30\xe4\x5a\x49\x20\xd2\x90\
|
||||
\x78\xcb\xf7\xee\x79\xc5\x3b\x66\x36\xf5\x39\x27\x31\xce\xcc\x1e\
|
||||
\xf0\x3c\x4f\x9e\xe7\x49\x92\x0e\x0b\x92\xf4\xd9\xef\xcb\x1b\x0c\
|
||||
\x04\x60\x03\x84\x61\xa8\x56\xab\x05\xc0\x66\xbb\xa1\x78\x57\xdc\
|
||||
\x03\xbd\xde\x07\xdd\xee\x3b\x00\xb7\x85\x82\x62\x00\x89\x44\x82\
|
||||
\x52\xa9\x04\x40\xe7\xad\xc3\x68\x34\x12\xc0\x70\x38\xd4\x6f\xb9\
|
||||
\x5c\xa9\xe0\x38\x0e\xcc\xa6\x3e\xb3\xa9\xcf\x72\xb1\xd0\x7d\xa5\
|
||||
\xac\x6c\x26\xad\xeb\x9c\xab\x66\xb3\xa1\x9c\x7b\xa5\x6c\x26\xad\
|
||||
\x6a\xf5\x41\xcb\xc5\x42\xb3\xa9\x8f\x39\xfc\x52\x32\x79\xa9\x5a\
|
||||
\xed\x85\xc9\x64\xb2\x9f\xb9\xae\x4b\xbd\xde\x20\x08\x56\x06\x38\
|
||||
\x06\x8c\x31\xba\x70\xe2\xbc\xb6\xdb\xcc\xe7\x5f\xa4\x52\x29\x1e\
|
||||
\x9f\x9e\x59\x87\xdf\x48\xfa\x0b\x00\x58\x96\x25\xcb\xb6\x19\x8f\
|
||||
\xc7\xe4\x6f\xf2\x44\xd1\x96\xdd\x6e\x67\xf6\x47\x4f\x89\xb3\x6d\
|
||||
\x5b\x8e\x13\x27\x5c\x87\xec\xa2\xc8\x1c\xed\x4e\xc9\x89\xa2\xc8\
|
||||
\x04\xc1\xea\x7f\x4c\xff\x00\xb4\xa0\x86\x57\x3b\x81\xd3\x82\x00\
|
||||
\x00\x00\x00\x49\x45\x4e\x44\xae\x42\x60\x82\
|
||||
\x00\x00\x03\x23\
|
||||
\x89\
|
||||
\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\
|
||||
\x00\x00\x10\x00\x00\x00\x10\x08\x06\x00\x00\x00\x1f\xf3\xff\x61\
|
||||
\x00\x00\x00\x04\x73\x42\x49\x54\x08\x08\x08\x08\x7c\x08\x64\x88\
|
||||
\x00\x00\x00\x09\x70\x48\x59\x73\x00\x00\x01\xbb\x00\x00\x01\xbb\
|
||||
\x01\x3a\xec\xe3\xe2\x00\x00\x00\x19\x74\x45\x58\x74\x53\x6f\x66\
|
||||
\x74\x77\x61\x72\x65\x00\x77\x77\x77\x2e\x69\x6e\x6b\x73\x63\x61\
|
||||
\x70\x65\x2e\x6f\x72\x67\x9b\xee\x3c\x1a\x00\x00\x02\xa0\x49\x44\
|
||||
\x41\x54\x78\xda\x75\x93\xdf\x4b\x14\x51\x14\xc7\xbf\x77\xe6\xce\
|
||||
\xce\xfe\xd2\x4d\x13\x95\x7e\x2c\x61\x44\x04\x66\x8a\x3f\x88\x0a\
|
||||
\x1f\x84\x42\xea\xb1\x87\x20\x24\x88\xac\xe8\x17\x59\x61\x84\x58\
|
||||
\x19\x2b\xf4\x90\x69\x50\x20\xf6\xe0\x4b\xf4\x50\x7f\x40\x12\xd9\
|
||||
\x4b\x61\x82\xa1\x0f\x45\x68\x92\x8a\x4b\x3d\xb4\x9b\xb3\xcd\xba\
|
||||
\xce\xec\xce\xcc\xce\xed\xde\x5d\x56\x54\xf2\x03\x87\x7b\x39\xe7\
|
||||
\x7c\xbf\x67\x0e\x33\x43\x18\x63\xd8\x00\xe1\xa1\x88\x18\x9d\x5a\
|
||||
\x28\x97\x24\x42\x5a\x6a\x77\xc5\x01\xd8\x3c\x2c\x1e\x2e\xd6\xb0\
|
||||
\xd1\x40\xbe\xf6\x74\xa4\x71\x3e\x66\x3c\x2e\xdd\x52\x5c\xbd\xb3\
|
||||
\xb2\xb8\x28\xe0\x55\x48\x3c\x61\x1a\x5a\xd2\x98\xad\x2a\xf7\x77\
|
||||
\xf4\xb4\x1d\x1e\x03\xe0\xfc\xcf\x40\x3a\x70\x6e\xb0\x4b\xf6\x15\
|
||||
\x75\xb7\x1f\xaf\x57\xab\x2a\x43\x50\x15\x19\xa2\x6c\x39\x2e\x62\
|
||||
\xba\x81\xb7\x93\x8b\x8e\xa6\x27\x06\x46\x22\x27\xbb\x84\xc9\x3a\
|
||||
\x83\xb2\x13\xbd\xb7\xb6\x56\x6e\xef\xbb\x73\xba\x19\x5a\xca\x86\
|
||||
\xbe\x62\xc3\xaf\xca\x10\x18\x99\x2c\x8a\x7c\x0a\xb6\x95\xaa\x78\
|
||||
\xf9\x71\x16\x73\xf3\xd1\xfb\xdf\x87\xcf\x47\x00\xb0\x9c\x01\x69\
|
||||
\xbc\xbe\x97\x96\x56\x4c\xdd\x6e\x6b\xf5\x9b\x16\xcb\x4d\x0d\xfa\
|
||||
\x28\xee\x9e\xda\x0f\x41\xe4\xd5\x57\xa4\x4c\x07\x84\x00\x21\xbf\
|
||||
\x82\x87\xaf\x3f\x98\x34\xa3\xd5\xa7\xde\xdc\x9b\x96\x20\xa0\x4a\
|
||||
\x6f\x73\xdd\x3e\x7f\x5c\xb7\xf8\x64\x0b\x49\xc3\x82\x91\x76\x20\
|
||||
\x4b\x44\x84\xb8\xf3\x5c\xbe\xf6\x73\xc9\xc0\x91\xea\x2a\xdf\x4a\
|
||||
\x1a\x91\x9c\x14\x02\x82\x06\x22\xab\xf8\xcb\xb3\x05\x96\xcd\x0c\
|
||||
\xae\x0e\x8e\x43\x3c\xa1\xc6\xd7\x59\x8b\x57\x51\x00\x89\xd6\xe7\
|
||||
\x0c\x48\xcd\xe5\x12\x04\xfd\x61\x22\x11\x2e\xb2\x50\x60\xa4\xe7\
|
||||
\x18\x0a\xb4\x3e\x18\x05\x61\x58\x7d\x83\xaa\x42\x00\xb0\x30\xa9\
|
||||
\xb9\x52\x42\x91\xf5\x12\x30\x17\xc9\x94\x0d\xaa\x38\xc8\x21\x7b\
|
||||
\x70\xa8\xfb\x1d\x3e\xf5\x1e\x85\x20\x95\xa5\x70\xdd\x2c\xf4\xe5\
|
||||
\x0c\xf4\x64\x12\xb1\x84\x09\x64\x6d\xc0\x26\x12\x65\xdf\xfa\x35\
|
||||
\x72\xf0\x66\x7c\x62\x66\xb1\x82\x28\x1e\x28\xde\x20\x68\x20\x00\
|
||||
\x4a\x15\x24\x12\x09\x08\xc6\xa2\x26\xb8\x03\x17\x58\x80\xc5\x4f\
|
||||
\x47\x88\x33\x71\x36\xfd\x6c\x89\x42\xe0\xb2\x1f\x70\xd2\x15\x8c\
|
||||
\x8b\x2d\xc9\xc3\x7b\x54\xc0\x91\xb0\x0a\x55\x01\x22\xe5\x83\xb9\
|
||||
\x40\x5a\x07\xec\xf4\x1c\x38\xf9\x2e\x89\x74\x22\x15\x73\x40\xe4\
|
||||
\x7c\xb3\xa2\x42\xeb\x6f\x42\x01\xed\x51\x1d\xa0\xfa\x73\x79\x80\
|
||||
\xf0\x44\x54\xec\xda\xb9\xee\x43\x22\x4d\x1d\x43\xf0\x85\x2e\x60\
|
||||
\x47\x2d\x10\x2c\x03\xdf\x25\x2f\xa2\xfc\x74\xd2\xf9\x9d\xf5\xdf\
|
||||
\xc0\xfc\x38\x60\xea\xcf\xd9\xc4\xc0\xc5\xf5\x06\x1c\x34\x76\x0c\
|
||||
\x43\xa6\x67\x20\xd5\x4a\xd8\x13\x02\xec\xdd\xf9\xa9\x9e\x05\x60\
|
||||
\xe6\x0f\x24\x67\xd2\x75\x1d\xfb\x05\x3e\x3f\x39\xcb\x38\xab\x06\
|
||||
\x6b\x21\x0d\x37\x5a\x54\x1f\x1d\x02\x95\xc3\x56\xc6\xf1\x88\xaa\
|
||||
\x12\xf0\xd8\x94\xe1\x97\x65\x5a\xed\xce\x58\xdf\xfb\x4d\xff\xc6\
|
||||
\x8d\x48\x35\x97\xc2\xa2\xca\xbe\x0c\x46\xb1\x09\xff\x00\x97\x08\
|
||||
\x2c\x5e\x2a\x10\x42\x0c\x00\x00\x00\x00\x49\x45\x4e\x44\xae\x42\
|
||||
\x60\x82\
|
||||
\x00\x00\x01\xf3\
|
||||
\x89\
|
||||
\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\
|
||||
\x00\x00\x10\x00\x00\x00\x10\x08\x04\x00\x00\x00\xb5\xfa\x37\xea\
|
||||
\x00\x00\x00\x02\x73\x42\x49\x54\x08\x08\x55\xec\x46\x04\x00\x00\
|
||||
\x00\x09\x70\x48\x59\x73\x00\x00\x01\xbb\x00\x00\x01\xbb\x01\x3a\
|
||||
\xec\xe3\xe2\x00\x00\x00\x19\x74\x45\x58\x74\x53\x6f\x66\x74\x77\
|
||||
\x61\x72\x65\x00\x77\x77\x77\x2e\x69\x6e\x6b\x73\x63\x61\x70\x65\
|
||||
\x2e\x6f\x72\x67\x9b\xee\x3c\x1a\x00\x00\x01\x72\x49\x44\x41\x54\
|
||||
\x28\xcf\x45\x91\x4f\x2b\x04\x71\x1c\xc6\xbf\xf3\x32\xe4\x6c\xde\
|
||||
\x80\xa2\x44\x39\xbb\xec\x1f\xb3\x23\x6d\x9b\x25\x8b\x10\xfd\x76\
|
||||
\x36\xec\xa2\x31\x89\x13\x0e\x2e\xca\xfb\x98\x4d\x7b\xf0\x12\xb4\
|
||||
\x85\x83\x36\x17\x97\xb1\xa2\xe9\x47\xfd\x0e\x63\xb6\x8f\x83\xb5\
|
||||
\x9e\xe7\xf6\xf4\xf4\x1c\x9e\x8f\x20\xbf\x3e\xb1\x8f\x83\x20\xf4\
|
||||
\x23\x3f\x0a\xc2\xe3\xe0\xc4\xfe\xcb\x05\x41\x7c\xeb\x50\xd5\x4d\
|
||||
\x95\x1a\x3e\x3e\x35\xaa\xd4\xcd\xa1\xf2\xad\x7e\xa1\x61\xd5\x9b\
|
||||
\xdb\xec\xd2\xa2\xcd\x13\x1d\x1e\x68\xb1\xc3\x36\xf5\x66\xc3\x42\
|
||||
\x04\xf1\xd4\x06\x17\xdc\xf3\x4a\xcc\x27\x5f\x68\xde\x78\xe6\x9c\
|
||||
\x0d\x3c\x85\x88\xb2\x37\x8d\xc7\x23\x1f\x18\xbe\xe9\xd1\x23\x25\
|
||||
\x41\xf3\x42\x8d\x4d\xa3\x6c\x59\x0f\x16\xb9\xe5\x1d\xc3\x15\x67\
|
||||
\x1c\xa0\xd8\x42\x91\xa2\x69\xb3\xc8\xfa\x91\x54\xc2\x15\xee\xd0\
|
||||
\xa4\x5c\xd2\xa0\x82\x4b\x8e\x59\x20\xa1\xcb\x1a\x95\x50\xca\x91\
|
||||
\x47\x9b\x98\x94\x3d\x96\xc9\x31\xc5\x38\xd3\x40\x4a\xcc\x3e\xe5\
|
||||
\x48\x4a\x51\x95\x47\x34\x3d\xb2\x8c\x32\x84\x30\xc4\x28\xd0\x43\
|
||||
\x73\x40\x29\x92\x62\x58\xee\x2f\xb8\x4c\x30\xc2\x30\x23\x4c\xf4\
|
||||
\x17\x96\x29\x86\x52\x0c\x1c\x6e\xe8\x92\xb0\xc4\x0c\x93\x8c\x31\
|
||||
\xc9\x0c\x90\xd0\xc1\xa1\x78\x24\xf3\x76\xc1\xac\xf2\x8c\x26\xe5\
|
||||
\x5f\x29\x1a\x8f\x82\x99\xb7\x05\x71\x55\x96\x53\x5e\xd0\x24\xa4\
|
||||
\x83\x1f\xae\xc9\xe2\x2a\x44\x90\x39\xcb\x6d\x66\x58\xa3\x4d\x97\
|
||||
\x18\x4d\x4c\x87\x2a\x19\xdc\xe6\x9c\xd5\x87\xe5\x5a\x8e\xca\x9b\
|
||||
\x0c\x25\x76\xd8\x63\x81\x0c\x79\xe3\x28\xd7\x1a\xd0\x44\x90\x82\
|
||||
\xed\x04\xf9\x30\x17\xe5\xa2\x7c\xe8\x04\x85\x01\xee\x1f\x8d\x42\
|
||||
\x66\xb3\xf5\x8b\xfe\x99\x00\x00\x00\x00\x49\x45\x4e\x44\xae\x42\
|
||||
\x60\x82\
|
||||
\x00\x00\x05\xb0\
|
||||
\x47\
|
||||
\x49\x46\x38\x39\x61\x10\x00\x10\x00\xf6\x00\x00\xff\xff\xff\x00\
|
||||
\x00\x00\xfa\xfa\xfa\x92\x92\x92\x88\x88\x88\xee\xee\xee\xc8\xc8\
|
||||
\xc8\xd8\xd8\xd8\x9e\x9e\x9e\x00\x00\x00\x8e\x8e\x8e\xc6\xc6\xc6\
|
||||
\x32\x32\x32\x52\x52\x52\xec\xec\xec\xa6\xa6\xa6\x94\x94\x94\xf2\
|
||||
\xf2\xf2\x82\x82\x82\x1c\x1c\x1c\xb2\xb2\xb2\xa4\xa4\xa4\x9a\x9a\
|
||||
\x9a\xf4\xf4\xf4\xf8\xf8\xf8\xa8\xa8\xa8\xce\xce\xce\x44\x44\x44\
|
||||
\x0c\x0c\x0c\x60\x60\x60\xde\xde\xde\xe8\xe8\xe8\xbc\xbc\xbc\x2a\
|
||||
\x2a\x2a\x36\x36\x36\x46\x46\x46\xd4\xd4\xd4\xc4\xc4\xc4\x3c\x3c\
|
||||
\x3c\x4e\x4e\x4e\x3e\x3e\x3e\x48\x48\x48\xd0\xd0\xd0\xca\xca\xca\
|
||||
\x5a\x5a\x5a\xb4\xb4\xb4\xea\xea\xea\x70\x70\x70\xac\xac\xac\xb8\
|
||||
\xb8\xb8\xba\xba\xba\x5e\x5e\x5e\x5c\x5c\x5c\x62\x62\x62\x86\x86\
|
||||
\x86\xe0\xe0\xe0\x7e\x7e\x7e\xfc\xfc\xfc\xa2\xa2\xa2\x18\x18\x18\
|
||||
\x2c\x2c\x2c\x56\x56\x56\x04\x04\x04\x50\x50\x50\xcc\xcc\xcc\x38\
|
||||
\x38\x38\x58\x58\x58\x1a\x1a\x1a\xf0\xf0\xf0\xd6\xd6\xd6\x9c\x9c\
|
||||
\x9c\xe2\xe2\xe2\xe6\xe6\xe6\x40\x40\x40\xaa\xaa\xaa\x24\x24\x24\
|
||||
\x20\x20\x20\xae\xae\xae\x72\x72\x72\x4a\x4a\x4a\x34\x34\x34\x6a\
|
||||
\x6a\x6a\xd2\xd2\xd2\xc0\xc0\xc0\x26\x26\x26\x7c\x7c\x7c\x42\x42\
|
||||
\x42\x54\x54\x54\x0a\x0a\x0a\x08\x08\x08\xb0\xb0\xb0\xe4\xe4\xe4\
|
||||
\x4c\x4c\x4c\xf6\xf6\xf6\xb6\xb6\xb6\x66\x66\x66\x68\x68\x68\xdc\
|
||||
\xdc\xdc\xa0\xa0\xa0\x12\x12\x12\x22\x22\x22\x00\x00\x00\x00\x00\
|
||||
\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
|
||||
\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
|
||||
\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
|
||||
\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
|
||||
\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x21\xff\x0b\x4e\
|
||||
\x45\x54\x53\x43\x41\x50\x45\x32\x2e\x30\x03\x01\x00\x00\x00\x21\
|
||||
\xfe\x1a\x43\x72\x65\x61\x74\x65\x64\x20\x77\x69\x74\x68\x20\x61\
|
||||
\x6a\x61\x78\x6c\x6f\x61\x64\x2e\x69\x6e\x66\x6f\x00\x21\xf9\x04\
|
||||
\x09\x08\x00\x00\x00\x2c\x00\x00\x00\x00\x10\x00\x10\x00\x00\x07\
|
||||
\x68\x80\x00\x82\x83\x20\x22\x26\x25\x83\x89\x00\x0b\x12\x1a\x00\
|
||||
\x21\x09\x09\x28\x8a\x82\x06\x0c\x09\x1b\x1e\x97\x09\x29\x82\x11\
|
||||
\x89\x04\x91\x1c\x16\x0b\x23\x27\x2a\x00\x18\x19\x9f\x82\x07\x0d\
|
||||
\x13\x1d\x1f\x94\x18\x8a\x0e\x14\x05\x94\x8a\x02\x08\x0f\xb9\x94\
|
||||
\x03\x91\x15\xbe\x00\x24\x88\xa1\x09\x16\xc3\xc5\x00\x05\x0a\x10\
|
||||
\x17\xc3\xd1\xd2\xa9\xbe\xb4\x89\x11\x19\xd6\x89\xaa\xac\x83\xdd\
|
||||
\x24\x24\xde\xd1\x25\x88\xd3\xd1\x81\x00\x21\xf9\x04\x09\x08\x00\
|
||||
\x00\x00\x2c\x00\x00\x00\x00\x10\x00\x10\x00\x00\x07\x6b\x80\x00\
|
||||
\x82\x83\x07\x34\x35\x37\x83\x89\x8a\x33\x09\x09\x2f\x39\x3a\x3d\
|
||||
\x19\x39\x83\x2b\x2f\x1a\x17\x2f\x8d\x38\x10\x3b\x09\x3b\x30\x83\
|
||||
\x2c\x09\x0d\x32\x2e\x12\x36\x05\x21\x8d\x09\x35\x83\x2d\x29\x31\
|
||||
\x05\x89\x15\x3c\x3e\x3c\x32\x83\x2e\x30\xb3\x8a\x30\x3f\x20\x8a\
|
||||
\xc2\xc3\x00\x25\x24\xc4\x82\x24\x25\x82\xc6\xc8\x00\xca\xce\xd1\
|
||||
\xd2\x83\x18\xc4\xd5\x89\x11\x19\xd7\x89\x18\x19\x11\x8a\xdf\xc9\
|
||||
\xc7\x82\xe1\xc4\x25\xcb\xd3\xc8\x81\x00\x21\xf9\x04\x09\x08\x00\
|
||||
\x00\x00\x2c\x00\x00\x00\x00\x10\x00\x10\x00\x00\x07\x68\x80\x00\
|
||||
\x82\x83\x02\x08\x0f\x83\x88\x89\x00\x03\x09\x09\x15\x00\x25\x12\
|
||||
\x2a\x89\x11\x82\x04\x8d\x16\x40\x41\x09\x26\x45\x83\x11\x19\x18\
|
||||
\x00\x05\x0a\x10\x17\x38\x3e\x8d\x46\x88\xa2\x89\x1e\x42\x43\x34\
|
||||
\x47\x8a\x8a\x0e\x14\x44\xb4\xb4\x20\x22\x26\x25\x90\x24\xb9\x00\
|
||||
\x21\x8d\x28\xbf\xc1\x0c\x8d\x29\xc1\x83\x0b\x23\x27\x93\xcb\xb9\
|
||||
\xad\x8a\xd3\x82\xa0\xd5\x82\x18\x19\x95\x88\xdc\x00\x24\xc0\xd6\
|
||||
\xcb\x25\xbe\xd1\xd1\x81\x00\x21\xf9\x04\x09\x08\x00\x00\x00\x2c\
|
||||
\x00\x00\x00\x00\x10\x00\x10\x00\x00\x07\x67\x80\x00\x82\x83\x84\
|
||||
\x85\x86\x82\x25\x25\x87\x83\x11\x83\x24\x24\x00\x44\x0b\x4e\x52\
|
||||
\x84\x11\x19\x18\x85\x0f\x49\x09\x51\x85\x99\x85\x48\x4a\x4f\x53\
|
||||
\x8b\x85\x1f\x30\x05\xa6\x85\x07\x34\x35\x37\x00\x25\x90\x8b\x33\
|
||||
\x09\x09\x2f\xb1\xb3\x87\x2f\xb6\x38\xab\x82\x2e\x12\x36\xaa\xab\
|
||||
\x46\x50\x0f\x9f\x86\x10\x4b\x09\x4c\x30\x8c\x98\x85\x21\xb6\x09\
|
||||
\x35\x96\x8e\x90\x15\x4c\x09\x54\x32\x8b\x89\x82\x4d\x51\xde\xbf\
|
||||
\x86\x81\x00\x21\xf9\x04\x09\x08\x00\x00\x00\x2c\x00\x00\x00\x00\
|
||||
\x10\x00\x10\x00\x00\x07\x68\x80\x00\x82\x83\x84\x85\x86\x82\x25\
|
||||
\x25\x87\x83\x11\x83\x24\x24\x8c\x85\x11\x19\x18\x86\x18\x19\x8d\
|
||||
\x84\x95\x87\x9b\x8b\x9e\x9f\x82\x02\x08\x0f\x88\x90\x8b\x03\x09\
|
||||
\x09\x15\x00\x25\xa6\x87\x04\xa9\x16\xa0\x00\x05\x0a\x10\x17\xa0\
|
||||
\x0b\x4e\x45\x85\x9d\x83\x2b\x56\x58\x56\xbc\x82\x93\x95\x20\x22\
|
||||
\x26\x25\x55\x3e\xa9\x46\x84\x99\x21\xa9\x28\x47\x57\x59\x42\x5b\
|
||||
\x87\x0c\xa9\x29\x00\x47\x5a\x1f\x8b\x0b\x23\x27\x2a\x86\x81\x00\
|
||||
\x21\xf9\x04\x09\x08\x00\x00\x00\x2c\x00\x00\x00\x00\x10\x00\x10\
|
||||
\x00\x00\x07\x67\x80\x00\x82\x83\x84\x85\x86\x82\x25\x25\x87\x83\
|
||||
\x11\x83\x24\x24\x8c\x85\x11\x19\x18\x86\x18\x19\x8d\x84\x95\x87\
|
||||
\x9b\x8b\x9e\x9f\x87\x25\x90\x9e\x24\x8a\x00\xa2\x9f\xa5\xa0\x8b\
|
||||
\x16\x50\x0f\x86\x5d\x20\x5d\x83\x46\x13\x09\x21\x19\x84\x44\x53\
|
||||
\x2c\x1a\x83\x5c\x09\xc1\x29\x07\x34\x35\x37\x0f\x49\x09\x60\x83\
|
||||
\x19\x43\x09\x3c\x32\x33\xc1\x2f\x1f\x5e\x5f\x0b\x84\x4d\x51\x32\
|
||||
\x00\x2f\xc1\x38\xab\x2e\x12\x36\x05\x86\x81\x00\x21\xf9\x04\x09\
|
||||
\x08\x00\x00\x00\x2c\x00\x00\x00\x00\x10\x00\x10\x00\x00\x07\x67\
|
||||
\x80\x00\x82\x83\x84\x85\x86\x82\x25\x25\x87\x83\x11\x83\x24\x24\
|
||||
\x8c\x85\x11\x19\x18\x86\x18\x19\x8d\x84\x95\x87\x9b\x8b\x9e\x20\
|
||||
\x22\x26\x8a\x9e\x82\x21\x09\x09\x28\x9e\x24\x8a\x0c\xa7\x29\xaa\
|
||||
\x8a\x0b\x23\x27\x2a\xa4\x84\x2b\x4e\x52\xb6\x00\x06\x41\x1c\x4f\
|
||||
\x61\x96\x84\x36\xa7\x1c\x16\x02\x08\x0f\x82\x97\x99\x00\x61\x5c\
|
||||
\x59\x33\x0e\x03\xa7\x15\x82\xcd\x82\x5b\x5a\x48\x00\x04\xa7\x16\
|
||||
\xbb\x05\x0a\x10\x17\x86\x81\x00\x21\xf9\x04\x09\x08\x00\x00\x00\
|
||||
\x2c\x00\x00\x00\x00\x10\x00\x10\x00\x00\x07\x68\x80\x00\x82\x83\
|
||||
\x84\x85\x82\x02\x62\x3d\x4a\x82\x25\x25\x86\x82\x46\x63\x09\x4c\
|
||||
\x19\x00\x24\x24\x83\x11\x84\x5c\x09\x9d\x4f\x85\x18\x19\x9a\x82\
|
||||
\x19\x64\x3e\x22\x32\x86\x18\x85\x30\x3f\x31\x8f\x84\x07\x34\x35\
|
||||
\x37\xb0\x84\x33\x9d\x2f\xb6\x24\x8e\x2f\x9d\x38\xbb\x8e\x2e\x12\
|
||||
\x36\x05\xb6\x85\x11\x32\x02\xc7\x83\x25\x42\x2b\x5d\xaa\x85\x2c\
|
||||
\x09\x0d\xaf\x84\xa1\xa3\x82\x53\x5f\x53\x44\x96\x98\x82\xda\x8f\
|
||||
\x8d\xcc\xe6\x81\x00\x3b\x00\x00\x00\x00\x00\x00\x00\x00\x00\
|
||||
\x00\x00\x03\x4a\
|
||||
\x89\
|
||||
\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\
|
||||
\x00\x00\x10\x00\x00\x00\x10\x08\x06\x00\x00\x00\x1f\xf3\xff\x61\
|
||||
\x00\x00\x00\x06\x62\x4b\x47\x44\x00\xff\x00\xff\x00\xff\xa0\xbd\
|
||||
\xa7\x93\x00\x00\x00\x09\x70\x48\x59\x73\x00\x00\x03\x76\x00\x00\
|
||||
\x03\x76\x01\x7d\xd5\x82\xcc\x00\x00\x00\x07\x74\x49\x4d\x45\x07\
|
||||
\xd7\x0c\x1b\x16\x0a\x05\x13\x29\x78\x6f\x00\x00\x02\xd7\x49\x44\
|
||||
\x41\x54\x78\xda\x8d\x92\xcf\x6b\x54\x57\x14\xc7\x3f\xf7\xbe\x37\
|
||||
\x6f\x5e\x66\x32\x93\xa9\x24\x1d\x27\x89\x10\x75\x5c\x34\xb5\x3f\
|
||||
\xd4\xaa\x7f\x81\x0b\x15\x17\xa1\xe8\x2a\xd0\x45\x6d\x17\x81\x2e\
|
||||
\xda\x95\xbb\x4a\x76\x5d\x15\x04\x41\x8b\x36\x5d\x74\x91\x62\xe9\
|
||||
\x1f\x10\x88\x6e\x5c\x88\xa0\xa8\xd8\x92\x90\x74\x88\x21\x93\xa8\
|
||||
\x33\x31\x33\xe3\xcb\xcc\xbc\x5f\xf7\x79\x78\x74\x21\xd2\x85\x07\
|
||||
\x0e\xe7\xbe\xfb\xee\xf7\x73\xbf\xe7\x70\x55\x6b\x7e\xfe\x68\xef\
|
||||
\xee\xdd\x9b\xad\x85\x85\x7d\x00\xc9\x5b\x09\x60\x80\x77\xf7\x9d\
|
||||
\xbd\x7b\xed\xca\xf4\xb4\xf7\x6a\x65\xe5\x8c\xaa\x5f\xba\x74\x2f\
|
||||
\x3c\x70\xe0\x64\x57\x29\xde\x37\x12\xa5\xd0\xad\x16\x2f\xaf\x5f\
|
||||
\xbb\xa3\x16\xb4\xde\xd8\x33\x3b\x3b\x66\x95\x4a\x24\x5a\xe3\x45\
|
||||
\x11\x05\xa9\xff\x17\xaf\x8d\x21\x6f\xdb\x68\xa9\x96\xd4\xa7\x33\
|
||||
\x33\x75\x1d\xc8\x47\xd0\xe9\x10\x78\x1e\xfe\xc1\x83\x94\x4f\x9d\
|
||||
\xa2\x1d\x86\xf8\xed\x36\x6f\xa7\xec\xa5\xff\xc2\x6a\x95\x60\x77\
|
||||
\x97\xb0\xdb\xc5\x17\xad\x0e\x21\x15\x27\x49\xc2\xe4\x89\x13\x94\
|
||||
\x2b\x15\xc6\xcf\x9e\xa5\xa7\x35\x81\x08\x25\xd3\xf5\xe8\xe9\xd3\
|
||||
\x8c\x94\xcb\x7c\x74\xfc\x38\x72\x36\x05\x44\x90\x02\x52\x07\xde\
|
||||
\xb3\x67\xac\xcc\xcd\x61\xa4\x85\xa2\xb4\x33\x3e\x35\x45\x9c\x1b\
|
||||
\x20\xca\xb9\x54\xce\x9d\x63\xb0\x58\x24\x0e\xc3\xf4\x8c\xb7\xb6\
|
||||
\x46\x24\x80\x10\xb0\xa3\x8c\x9d\x3a\x40\x84\xcf\xef\xdf\x27\xdc\
|
||||
\xf5\xd8\xff\xf5\x45\xdc\x7c\x9e\xd1\xf3\x17\xe4\x36\x83\x93\xcb\
|
||||
\x61\x44\x5c\x9b\xbb\x49\xf3\xe9\xdf\x80\x22\x5b\x1a\x4a\x01\xd6\
|
||||
\x54\x36\xf3\x43\xe0\x64\x8b\xb1\x00\x94\x89\x31\xcd\x3a\xf1\x46\
|
||||
\x8d\xfc\x67\xc7\x30\x5a\x83\xb6\xd0\x62\x79\xe7\x8f\x5f\xe9\x3c\
|
||||
\x79\x48\xaf\xd9\xa4\xbd\xbe\xc1\xfa\xe2\x22\x7e\xbf\xff\xda\x8e\
|
||||
\x2c\x8b\xf6\xe3\xc7\x98\x24\xa6\x58\x74\x28\xed\x71\xe9\xf5\xb7\
|
||||
\x51\x67\xbe\x64\xb0\xf4\x01\x91\x80\x77\x5e\x6d\xb3\xb9\xf0\x17\
|
||||
\xc9\xf2\x3f\x78\x5d\xf0\xfa\x9a\xd8\x76\x09\x01\x1d\xdb\x16\x89\
|
||||
\x02\xe9\x84\xac\x0e\x50\xfb\xc6\x99\xb8\x7c\x85\xd2\xf0\x08\x16\
|
||||
\x06\x2b\x31\x64\x07\x0b\x7c\xf8\xe3\x55\x32\x93\x87\x91\x91\xe0\
|
||||
\x66\x15\xb6\xad\x49\x01\xc6\x56\x0a\xad\x70\x6c\x70\x0f\x7f\xca\
|
||||
\xc7\x57\xe7\x19\x19\x1b\xc7\xd1\x90\xbb\x3e\xc3\xd0\xdc\x77\xb2\
|
||||
\x56\x0c\x09\x70\xe2\xa7\xdf\xc8\x7e\x72\x04\xc7\x01\x2b\xa3\xfe\
|
||||
\x73\x90\xd1\x28\x0d\x45\x79\x03\x5f\xdc\xf8\x93\x91\x51\x11\x5b\
|
||||
\xc2\xbc\xf2\x0d\xee\xf2\x6d\x0a\xff\xde\x61\xf8\xf7\xef\x29\xe6\
|
||||
\x73\x0c\x8f\x8e\xf1\xf9\xb5\x5b\x14\xaa\x87\xb0\x05\x10\xa5\x0e\
|
||||
\x84\x0e\xe0\x37\x1a\x38\xad\x06\x16\x32\xb0\xd9\xaf\xf0\x1f\x2e\
|
||||
\x92\x00\x26\x81\xf8\xd1\x6d\xcc\xcf\xdf\x32\xe0\x64\xc8\xb4\x9a\
|
||||
\x84\xdb\x0d\x94\x05\x06\x50\x37\x8e\x56\x9f\xf7\x6a\xf5\x72\x4e\
|
||||
\xc7\x72\xc3\x10\x95\xc9\x2a\x6a\xed\x01\x85\x1c\x69\xbf\x96\x06\
|
||||
\x3f\x00\xaf\x07\xf1\xc4\x31\x5e\x2e\xd5\xd8\x69\xb4\xe9\x3b\x05\
|
||||
\x96\x6a\xdb\x75\xdb\x2d\xef\x5f\x37\x41\x54\x56\xdd\x0e\x3d\x13\
|
||||
\xf3\x62\x75\x99\x01\x77\x10\x1f\x70\x22\x40\x41\x6c\x20\xd0\xd0\
|
||||
\x5b\x59\xa6\x1b\x42\x24\x43\xf5\xfa\x03\xe2\xc2\x5a\xb5\xb7\x96\
|
||||
\x56\xa7\x3b\x9b\x5b\xbf\x84\xbe\x5f\x4d\x78\xbf\x50\x5a\x23\xb9\
|
||||
\x2a\xaf\xf6\xe2\x1b\x6a\x91\x52\x21\x98\x91\x3a\x79\x00\x00\x00\
|
||||
\x00\x49\x45\x4e\x44\xae\x42\x60\x82\
|
||||
\x00\x00\x04\x3d\
|
||||
\x89\
|
||||
\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\
|
||||
\x00\x00\x10\x00\x00\x00\x10\x08\x06\x00\x00\x00\x1f\xf3\xff\x61\
|
||||
\x00\x00\x00\x06\x62\x4b\x47\x44\x00\xff\x00\xff\x00\xff\xa0\xbd\
|
||||
\xa7\x93\x00\x00\x00\x09\x70\x48\x59\x73\x00\x00\x37\x5c\x00\x00\
|
||||
\x37\x5c\x01\xcb\xc7\xa4\xb9\x00\x00\x03\xaf\x49\x44\x41\x54\x38\
|
||||
\xcb\x05\xc1\x5b\x68\x1c\x55\x00\x06\xe0\xff\x9c\x33\x97\x9d\xd9\
|
||||
\x5b\x92\xcd\x65\xd3\x24\xdd\x6e\xd2\xb4\x69\x62\x52\xa4\xd6\x34\
|
||||
\xa2\x85\x16\x8b\x97\x97\x12\xa1\x16\x6c\x51\xfb\xa2\x14\xaa\x0f\
|
||||
\x8a\x10\x2d\xf8\x52\x6b\x0b\x62\x14\x7c\x28\x4a\xa9\x50\x44\xa9\
|
||||
\xa4\xe0\x8b\xb7\xb4\x18\x30\x92\x12\x42\xad\xb5\x95\x90\xd0\x68\
|
||||
\x2f\xc9\xee\x26\xd9\xcb\xcc\xec\xcc\xec\xec\xcc\xec\x39\x7e\x1f\
|
||||
\x99\xfc\x62\x06\xaa\x2a\xa1\x52\xae\x92\x03\x07\x87\xc8\x53\x7b\
|
||||
\xb7\xf2\xb3\x67\x7e\xde\x56\x28\xd7\xf6\xd7\x82\xc6\x8e\x5c\xde\
|
||||
\xc2\xed\x3b\xb9\xe5\xc0\xad\xff\x16\x2a\xea\x6a\xac\x49\x23\xa1\
|
||||
\x1f\x82\x4a\x54\x40\x00\xd2\xd2\x72\x11\x94\x80\x3c\x58\x2c\x88\
|
||||
\x6a\xc5\xef\x98\x99\x59\x3e\x1b\x69\x4b\x1c\xcd\x6c\x69\x89\x3e\
|
||||
\xda\xb0\x45\x2e\xef\x40\xed\x6c\x26\xcc\xad\x5b\x81\xeb\x5f\xae\
|
||||
\x6e\x98\x1f\x1a\x6b\xc5\x4a\xef\xe3\xbd\x44\x8d\x48\x82\xed\x1a\
|
||||
\x3c\x4c\xec\x92\x23\xea\x10\xbd\x03\xbb\x7b\xa6\xb5\xee\xd4\x21\
|
||||
\xaf\xbd\x45\x5a\x63\xb2\xc8\x87\x54\x74\x76\x26\x85\x1c\x8b\x40\
|
||||
\x8b\x45\x14\x89\xd1\x51\xca\xe8\x61\x16\x51\x7f\x32\x2a\x6e\x85\
|
||||
\x32\x4a\x08\x90\x05\xb0\x55\x3b\xfd\xd1\x07\xb3\xed\x03\x5d\x7b\
|
||||
\xc2\x54\x34\x68\x6a\x92\x25\x08\x46\xfe\x7e\x68\x8a\xb5\x75\x07\
|
||||
\x8a\x17\x90\xdc\x83\xa2\x08\x4c\x37\xac\x97\x6c\xd9\x33\x9c\x9b\
|
||||
\x3a\x0f\x9f\x09\x3c\x5e\x63\x27\xdf\xb9\x84\x6d\xdb\x87\xde\xcd\
|
||||
\x0c\xf5\xbc\x6a\xc3\x09\xe6\xaf\x7c\x2e\xaf\xcd\xfd\x8a\x1e\x6e\
|
||||
\x92\x37\x5f\x1c\x25\x1d\x1a\x27\x4b\x79\x13\xd5\x3a\x81\x61\xd5\
|
||||
\x98\xef\x87\x41\xe8\x85\xdd\x1c\xb0\x0d\x2f\xfc\x83\x5e\x98\x7c\
|
||||
\x49\x76\x05\x39\x4e\x34\x05\x1b\x2e\x67\x85\x64\x3f\x6e\x45\x07\
|
||||
\xc8\x95\x5b\xf7\xa1\x4a\x0c\xfb\xba\x22\x78\xb6\xb5\x84\xed\x69\
|
||||
\x95\xc4\x12\x3a\x88\x2c\xb1\x78\x8b\x8e\x74\x47\xe2\xf5\x8d\xbc\
|
||||
\xa9\xb3\x78\xe7\xe9\x21\xb9\x29\x36\xc1\xa3\xaa\x54\x95\x75\x44\
|
||||
\xfb\x46\x48\xac\x6f\x04\x2f\x8f\x0d\x81\xaf\xdf\xc3\xf1\xb7\x26\
|
||||
\x70\xfb\xcf\x05\x8c\x3f\x91\x86\x13\x2a\x58\x5a\xad\xe3\xe9\x91\
|
||||
\x4e\xe2\x39\x7e\xb2\x62\x79\x3f\xb0\xfe\xe1\xf1\x11\xaa\x2b\x27\
|
||||
\x2c\x50\x11\x4f\x28\x78\x64\x08\xf2\x64\xab\x8c\xe7\x52\x65\xbc\
|
||||
\x71\xee\x22\xea\x7d\x87\x50\xd7\xba\xb0\x70\xed\x2a\x0c\x97\x80\
|
||||
\xc6\x32\x30\x4a\x16\xca\x25\x87\x25\x74\x79\x4a\x8a\x46\x15\xcf\
|
||||
\xf2\x42\xd0\x9a\x07\xd7\x51\x30\x1a\xbd\x86\x53\x3b\xbb\xf1\xf1\
|
||||
\xe5\xff\x80\xfe\xe7\xb1\xb5\xf7\x31\xd4\x4c\x0b\x1b\x0d\x1d\x7a\
|
||||
\x22\x85\xa4\x60\x28\xe6\xeb\x50\x01\x14\xcb\xae\x47\x63\x5a\x64\
|
||||
\x85\xf0\xb0\x58\xb5\x08\xd1\xcc\x79\x9c\xdb\x7b\x01\x85\x1b\x27\
|
||||
\x70\x63\x35\x44\x4b\x5b\x2f\xaa\x85\x02\x02\xdb\x81\xde\x9c\x05\
|
||||
\x65\x51\xe8\x32\x90\xd4\x15\xe2\x38\xfe\xa6\x69\x7a\x2b\xf4\xe6\
|
||||
\x66\x3c\xcf\xa8\xf2\xbb\xe2\x17\xf1\xde\x9e\x2f\xb9\xd4\xd8\xc4\
|
||||
\x67\xd3\x7d\xe0\xb1\x11\xf8\xa6\x01\xdf\x09\x60\x1b\x35\x48\x81\
|
||||
\x27\xba\x9a\x15\x90\x86\x68\x94\x4a\x36\xbc\x7a\x38\xab\xb5\xc6\
|
||||
\xf3\xd4\xbc\xd3\x84\xbb\xff\x46\x3f\x39\x35\x76\x15\x63\x3b\x73\
|
||||
\xe4\x9b\x69\xce\x57\xc4\x31\x34\x69\xba\x08\xac\x1a\xe4\x46\x03\
|
||||
\xd9\x94\x26\x32\x29\x9d\x14\x72\x26\x7f\xb8\x5a\x21\x01\x87\x90\
|
||||
\x64\xf6\xa9\x2e\x53\x48\xf7\xbf\x7e\x01\xf9\xa2\xe8\x1b\xde\xd5\
|
||||
\x8e\xbf\xee\xda\xf8\x6a\xfe\x20\x51\xfb\x86\x79\x77\x94\x13\x9b\
|
||||
\x52\x11\x51\x18\x1c\xd3\xc1\xe2\xaa\xd9\x88\xe8\x2a\xb8\xaa\x30\
|
||||
\x1a\xf0\xf7\xa5\xa4\x3e\x87\x06\xa7\x74\xbd\xc4\x07\xb3\xd9\x8e\
|
||||
\x49\xb7\xe6\xe1\xe2\x8f\xca\x9a\x9f\x7e\xa5\x1c\x4d\x37\x53\x57\
|
||||
\x4f\x20\xd9\xdd\x4e\x0c\xa6\x92\x3c\x22\x48\x64\xb7\x30\xb5\x25\
|
||||
\xe1\x53\x4a\xdf\xce\xee\x1f\x3a\xaf\x69\x0a\xc9\xf4\xa7\x39\xdb\
|
||||
\xb7\x3b\x7e\xb4\xbd\x99\x1c\x99\x59\xa8\xd8\x67\x2e\x85\xaf\x85\
|
||||
\x35\xe9\x3b\xdb\x32\x32\x65\xbb\xde\x52\xa8\x38\x0a\xe7\x75\x2e\
|
||||
\x37\x2c\xd3\xdf\x5c\x99\xb5\xef\xcd\x9d\x54\xd2\xfd\xdf\x57\x56\
|
||||
\x0a\x34\x77\xfd\x5b\x61\x98\x04\x04\x48\xd2\x23\x07\xcc\x09\xcb\
|
||||
\x01\xff\x65\x1e\xe7\xe3\x3a\x3a\xec\x1a\xd2\x04\x74\x87\x1c\x49\
|
||||
\x75\x06\x0d\x34\x44\x50\x5c\x05\xc4\x22\x08\x2b\xb4\x0d\x8e\xbb\
|
||||
\x9b\xff\x4c\x85\x00\x70\x6c\x4a\xe0\x7f\x70\x2b\xc1\xc5\x00\xe2\
|
||||
\xed\x86\x00\x00\x00\x22\x7a\x54\x58\x74\x53\x6f\x66\x74\x77\x61\
|
||||
\x72\x65\x00\x00\x78\xda\x2b\x2f\x2f\xd7\xcb\xcc\xcb\x2e\x4e\x4e\
|
||||
\x2c\x48\xd5\xcb\x2f\x4a\x07\x00\x36\xd8\x06\x58\x10\x53\xca\x5c\
|
||||
\x00\x00\x00\x00\x49\x45\x4e\x44\xae\x42\x60\x82\
|
||||
\x00\x00\x01\xf5\
|
||||
\x89\
|
||||
\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\
|
||||
\x00\x00\x10\x00\x00\x00\x10\x08\x04\x00\x00\x00\xb5\xfa\x37\xea\
|
||||
\x00\x00\x00\x02\x73\x42\x49\x54\x08\x08\x55\xec\x46\x04\x00\x00\
|
||||
\x00\x09\x70\x48\x59\x73\x00\x00\x01\xbb\x00\x00\x01\xbb\x01\x3a\
|
||||
\xec\xe3\xe2\x00\x00\x00\x19\x74\x45\x58\x74\x53\x6f\x66\x74\x77\
|
||||
\x61\x72\x65\x00\x77\x77\x77\x2e\x69\x6e\x6b\x73\x63\x61\x70\x65\
|
||||
\x2e\x6f\x72\x67\x9b\xee\x3c\x1a\x00\x00\x01\x74\x49\x44\x41\x54\
|
||||
\x18\x19\x05\xc1\x41\x4b\x53\x01\x1c\x00\xf0\xff\x3b\xf5\x11\xea\
|
||||
\xda\xa1\x7d\x84\x2e\x5d\x3c\x46\x17\x75\x6d\xb3\x18\x96\x42\x9a\
|
||||
\xa8\x20\x6f\x13\x6b\x96\xcc\x87\xe8\xcd\xba\x74\xea\x63\x04\x6f\
|
||||
\x84\x41\x5f\xa0\xa8\x41\x79\x08\xf1\xe2\x65\x19\xc5\x7a\x06\xef\
|
||||
\x30\xde\xf8\xf5\xfb\x85\x10\x42\x1c\xd6\x0e\xb2\x2c\xef\x8f\xfa\
|
||||
\xa3\x2c\x3f\xc8\x0e\x6b\x42\x08\x11\x42\xf4\x93\xbd\xb4\x57\x76\
|
||||
\x6c\xeb\xeb\xdb\xd6\xd1\x2b\xf7\xd2\x7e\x22\x44\x88\xdd\xa4\x37\
|
||||
\xd8\xf2\xcc\x89\xa1\x1f\xce\x7c\x77\x62\xc7\x96\xde\x60\x37\x11\
|
||||
\x21\xba\xe9\x86\x57\xbe\xf9\x69\xec\xca\x3f\x85\x5f\xce\x1d\xdb\
|
||||
\xd0\x4d\x45\xa4\xb5\xcd\xb2\xeb\xd4\x1f\xa5\x77\xae\x4c\x55\x26\
|
||||
\x0a\x17\xb6\x6d\x96\x69\x2d\xd6\xb3\x65\x1f\xfd\x56\x9a\x3a\x76\
|
||||
\xe4\x2b\xa8\x14\x86\x96\xad\xef\xc7\x4a\xbe\xea\x8b\x42\x85\x3d\
|
||||
\xab\x1e\x78\xed\x0a\x13\x97\xd6\xac\xe4\xb1\x34\xea\x1a\x1a\xab\
|
||||
\xb0\x6a\xde\x8c\x19\x8f\x7c\x56\x19\x7b\x61\x69\x14\x8b\xa3\x8e\
|
||||
\x53\x85\x29\x6e\xbb\xee\x9a\x5b\xee\xfb\x64\xaa\xf0\xd2\xe2\x28\
|
||||
\xda\xf9\x92\xa1\xb1\x0a\x77\xdc\x74\x43\xc7\x5f\x54\xc6\x9e\x68\
|
||||
\xe7\xd1\xce\x1a\xde\xbb\x34\xc1\x3d\x77\x7d\x00\x4c\x9c\x69\x68\
|
||||
\xef\xc7\xc3\x5a\xb3\x7c\xea\x5c\xa1\xf2\x46\x01\xa8\x14\xba\x9a\
|
||||
\xe5\xc3\x5a\x88\x56\x3a\xe7\xc8\x85\xc2\x44\x65\xaa\x32\x51\x78\
|
||||
\x6b\x4e\x2b\x15\x21\x16\x92\xd6\x60\xd6\x9a\xa1\x4b\x63\x85\xb1\
|
||||
\x33\x1d\xb3\x5a\x83\x85\x44\x84\x10\xad\xa4\x91\xd6\xcb\x59\x8b\
|
||||
\x76\x3c\xf7\xd8\xac\x7a\xd9\x48\x5b\x89\x10\x21\x84\x10\xcd\x5a\
|
||||
\x23\xab\xe7\xf3\xa3\xf9\x51\x3d\x6f\x64\xcd\x9a\x10\x42\xfc\x07\
|
||||
\x7b\x2d\x6e\x9f\x2f\x2d\x37\x8c\x00\x00\x00\x00\x49\x45\x4e\x44\
|
||||
\xae\x42\x60\x82\
|
||||
\x00\x00\x01\xe5\
|
||||
\x89\
|
||||
\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\
|
||||
\x00\x00\x10\x00\x00\x00\x10\x08\x06\x00\x00\x00\x1f\xf3\xff\x61\
|
||||
\x00\x00\x00\x01\x73\x52\x47\x42\x00\xae\xce\x1c\xe9\x00\x00\x00\
|
||||
\x06\x62\x4b\x47\x44\x00\xff\x00\xff\x00\xff\xa0\xbd\xa7\x93\x00\
|
||||
\x00\x00\x09\x70\x48\x59\x73\x00\x00\x06\xec\x00\x00\x06\xec\x01\
|
||||
\x1e\x75\x38\x35\x00\x00\x00\x07\x74\x49\x4d\x45\x07\xd8\x03\x14\
|
||||
\x12\x23\x3b\xba\x62\x67\xa1\x00\x00\x01\x65\x49\x44\x41\x54\x78\
|
||||
\xda\x95\x90\xcf\x4a\xc3\x40\x10\xc6\x67\x37\xa6\xa5\x81\x5e\x8a\
|
||||
\xa7\x3c\x86\x78\xf1\x01\xd4\x1e\xac\x6f\xe0\xc5\x73\xbd\xd8\x53\
|
||||
\x2d\xf8\x08\xbe\x4b\xcf\x3e\x80\xa0\x10\x3c\xfb\x00\x56\xda\x54\
|
||||
\x4a\x82\x25\x7f\x77\x3a\xb3\x6c\xe8\x9a\x90\xa2\x1f\x7c\x7c\xbb\
|
||||
\xec\xcc\x6f\x77\x56\x00\xc0\x80\x7c\x46\x16\x70\x58\x48\x7e\x21\
|
||||
\x7f\x43\x4d\x57\xf8\x37\x31\x60\x04\x35\x1d\x55\x37\xaf\xc2\x10\
|
||||
\xa4\x94\x20\x85\x00\x41\x29\x38\xd9\xa6\xb0\xdf\xef\x73\x88\x26\
|
||||
\xc0\xc8\x71\x1c\x0d\x88\xa3\x08\x82\x20\x00\x2d\x0b\xd0\xed\x76\
|
||||
\x39\x4e\xc8\xa9\x35\xd2\x2b\x2f\x46\x48\xda\x6c\x36\x18\xc5\x31\
|
||||
\xce\xe7\x73\xfc\xc7\x48\xc3\xc6\x0b\xf8\x56\x56\xb8\x5e\x83\xc3\
|
||||
\x23\x19\x0b\xb2\x3d\x92\xe7\x79\x1c\xb2\x02\xe8\x22\x0d\x31\x00\
|
||||
\xdd\x4c\x7b\x9d\x55\x33\x67\xdb\x1f\x48\xab\xd0\xec\xf7\x10\xeb\
|
||||
\x53\xa1\x15\x60\x15\xd9\x40\xa7\x06\xa6\x6c\x00\xea\x07\x36\x60\
|
||||
\x0f\x3e\x0c\x68\x42\x44\xad\xb9\x28\x0a\x08\xc3\x10\x3a\x1d\x17\
|
||||
\x7a\x3d\x0f\x14\x08\xa4\xb2\x82\x01\x8a\x0e\xd1\x75\x5d\x51\xdd\
|
||||
\xac\xb3\x76\x2b\x37\xfb\xbe\x0f\xac\xed\xf6\x07\x1e\x67\xb3\x67\
|
||||
\x5a\x06\xbc\x3f\x26\xdf\x90\x6f\x8d\x9f\x90\x94\x24\x09\x66\x59\
|
||||
\x86\x0c\x2f\xcb\x12\x17\x5f\x0b\x54\x4a\x61\x1c\xc7\x38\xbe\x1b\
|
||||
\xbf\x51\xdd\x29\xb4\x68\xc8\x80\x34\x4d\x31\xcf\x73\x06\xe8\xc6\
|
||||
\xe5\x6a\xa9\x9b\x27\x93\xfb\x77\xaa\xb9\x26\xcb\x36\xc0\x05\x35\
|
||||
\x2a\xb4\x94\x15\x25\x7e\x2e\x57\x38\x7d\x98\xf2\x93\x2f\x7f\x7d\
|
||||
\x3e\x34\x35\x20\x9f\x9b\x22\x5b\x68\x66\xfe\x20\x2b\x30\xda\x01\
|
||||
\x68\x0b\xe8\x88\x71\x7b\x2b\x7d\x00\x00\x00\x00\x49\x45\x4e\x44\
|
||||
\xae\x42\x60\x82\
|
||||
\x00\x00\x03\x47\
|
||||
\x89\
|
||||
\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\
|
||||
\x00\x00\x10\x00\x00\x00\x10\x08\x06\x00\x00\x00\x1f\xf3\xff\x61\
|
||||
\x00\x00\x00\x04\x73\x42\x49\x54\x08\x08\x08\x08\x7c\x08\x64\x88\
|
||||
\x00\x00\x00\x09\x70\x48\x59\x73\x00\x00\x01\xbb\x00\x00\x01\xbb\
|
||||
\x01\x3a\xec\xe3\xe2\x00\x00\x00\x19\x74\x45\x58\x74\x53\x6f\x66\
|
||||
\x74\x77\x61\x72\x65\x00\x77\x77\x77\x2e\x69\x6e\x6b\x73\x63\x61\
|
||||
\x70\x65\x2e\x6f\x72\x67\x9b\xee\x3c\x1a\x00\x00\x02\xc4\x49\x44\
|
||||
\x41\x54\x78\xda\x9d\x93\x5b\x48\x53\x71\x1c\xc7\x3f\xe7\x6c\xe9\
|
||||
\xa6\x36\x8f\xb5\x91\xa7\x48\x6c\x0b\x32\x8c\x08\xa4\xfb\x58\x2d\
|
||||
\xbb\x88\xd5\x53\x62\x17\x8b\xae\xf3\xb5\xb2\x46\x17\x24\x28\xba\
|
||||
\x47\x05\x41\x85\xbd\x44\x74\x2f\x0d\x2a\x95\x82\xc0\x82\x6e\x08\
|
||||
\x25\xdd\x2f\x76\xa3\x8b\xb5\x6a\x73\xd3\xed\x2c\xdd\x39\xae\x79\
|
||||
\x40\x5d\xf4\x12\x7d\xe1\xfb\x76\xbe\x1f\xbe\xbf\xef\x9f\x23\xc4\
|
||||
\xe3\x71\xfe\x45\xd5\x6b\xe4\x41\x79\xcf\xf3\x1b\xd4\x48\xf4\x4d\
|
||||
\x3f\x59\x2e\xcf\xaf\xae\xfe\x06\xa0\x03\xe6\xce\x99\xd3\xfa\xeb\
|
||||
\x57\x87\xb4\x7a\xad\x97\x64\x09\x22\x80\x88\x40\x8c\x91\x6c\xe1\
|
||||
\x63\xad\x84\xe5\xf2\x0b\x9e\x29\x0a\x17\x26\x4e\x0c\x5e\xa9\xab\
|
||||
\xcb\x32\x02\x28\x11\x45\xca\x96\xb3\x71\x4d\x75\x13\x4f\x06\x74\
|
||||
\x5b\x88\x13\x7d\xb4\x98\x1f\x3e\x91\x65\xf5\xaf\xf1\x48\x22\xb6\
|
||||
\x9f\x61\xc4\xd6\xa0\x04\xa0\x03\xba\xba\xba\x30\xa5\x9a\x30\xa5\
|
||||
\x18\x38\x79\xe3\x31\xc9\xca\xf4\x1d\x64\x8c\xf5\x15\x0b\x2b\x15\
|
||||
\x04\xd5\x4f\x91\x37\x85\x9a\x9b\x23\x09\xbe\x35\xd2\x0b\xd0\x12\
|
||||
\x00\x55\x55\x11\x45\x58\x5c\x38\x0a\x01\xf4\x26\xaf\x1a\xab\xc8\
|
||||
\xb5\x3c\xa5\xb8\xa2\x03\xff\xcf\xef\x9c\xdd\x9a\x46\x28\x65\x1a\
|
||||
\xb7\xdf\xb4\x24\x32\x1a\x00\x62\x4f\x03\x4d\xd3\x68\x8f\x76\x12\
|
||||
\xed\x54\x51\x12\x7e\xff\xbc\x96\xbc\xd4\xe3\x94\x6d\xed\xe4\xdd\
|
||||
\xc7\x00\x47\xd6\x9b\x21\x2d\x8f\xc6\x2f\x13\x30\x99\xcd\x00\xf4\
|
||||
\x9d\xa0\x69\x7a\x83\x70\x02\x70\xfe\xda\x3d\x52\x63\xef\xf1\x4c\
|
||||
\x7e\x4d\xf9\x2e\x81\x47\x2f\x43\x6c\x28\x53\xc9\xb0\x48\xec\xbe\
|
||||
\x32\x8c\xd9\x33\x25\xa4\xcc\x4c\xda\xdb\xda\xfe\x6e\xd0\x16\x8e\
|
||||
\xe2\x1a\x6d\xc5\x33\xc5\xcf\xe1\x73\x9f\xb8\xdb\x14\x62\xc9\xf4\
|
||||
\x08\xee\x82\x74\x2e\x36\xcd\x20\x7f\xc4\x70\x0a\xc6\xbb\xba\xbf\
|
||||
\xd7\x9d\x34\xa2\x86\xa6\xaa\x6c\x5b\xb7\x82\x03\xde\xa1\x9c\xbe\
|
||||
\xfe\x95\xaa\xd3\x2f\x28\xc8\xfd\x4c\x59\xa1\x91\xe5\x7b\x44\x82\
|
||||
\x91\x06\x1c\x0e\x07\x6f\x9f\x3c\xa0\x27\xd3\x37\xa2\x96\x20\x6a\
|
||||
\x9d\x6c\x5c\xaa\x71\xeb\xc6\x25\xf6\x9e\xca\x22\x77\xa0\x8f\x1d\
|
||||
\xe5\x06\x56\xed\x4b\xe3\xab\x3f\x8e\x7d\x58\x36\x46\x83\x41\x3f\
|
||||
\xb5\x27\xf3\xc7\x06\x2b\xa7\x7f\xa0\xf5\x9b\x9f\xed\x67\x24\x06\
|
||||
\x59\xda\x38\xe6\x85\xfd\x97\xed\x08\x19\x56\x36\x6e\x9a\x87\xcb\
|
||||
\xe5\xa2\x74\x5e\x89\x7e\xaa\xc3\x6e\xd7\x33\xbd\x1b\x38\x0b\x72\
|
||||
\x49\x4f\x37\x50\x71\xd4\x42\x7f\xb3\xca\xe1\xd5\xed\xec\x3a\xd5\
|
||||
\x45\xc3\x03\x8d\x9c\x9c\x1c\x64\x59\xa6\xb9\xb9\x19\x79\xf0\x60\
|
||||
\x44\xa3\x41\x7f\xf6\x98\xaa\xf6\x01\x0a\xdd\x93\x90\xc7\x6c\x27\
|
||||
\xd3\x62\x62\x9f\xe7\x3b\x57\xef\x08\x9c\xa8\x8f\x61\xb3\xd9\x70\
|
||||
\x3a\x9d\x84\x42\x21\xdd\xf1\xee\xf1\x12\xd5\xad\x56\x2b\xb1\x58\
|
||||
\x0c\x1d\xb0\xad\x62\xbe\x71\xc8\x10\x1b\x4a\xa0\x91\x35\x0b\x24\
|
||||
\xee\xbf\xb4\x72\xa8\x26\x8d\x01\x52\x16\xc5\xc5\xc5\x84\xc3\xe1\
|
||||
\x5e\x40\x24\x12\xd1\x83\x51\x45\xd1\x47\x07\x30\xf6\x33\x65\x6c\
|
||||
\xae\xdc\x59\xc5\xac\xb1\x16\xf5\x6c\xbd\xcf\xe8\x2e\x2a\x65\xf9\
|
||||
\x4a\x03\x00\x81\x40\x80\x64\x7d\x69\x69\x01\xe2\x3c\x6c\x6a\x42\
|
||||
\x34\x88\x41\x00\x2a\x56\x15\x2d\xf2\x94\x8c\x73\x74\xff\x95\xff\
|
||||
\xe3\xdf\xfd\x96\x70\x9f\x9f\x28\xbe\x9f\x00\x00\x00\x00\x49\x45\
|
||||
\x4e\x44\xae\x42\x60\x82\
|
||||
\x00\x00\x02\x84\
|
||||
\x89\
|
||||
\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\
|
||||
\x00\x00\x10\x00\x00\x00\x10\x08\x03\x00\x00\x00\x28\x2d\x0f\x53\
|
||||
\x00\x00\x00\x03\x73\x42\x49\x54\x08\x08\x08\xdb\xe1\x4f\xe0\x00\
|
||||
\x00\x00\x09\x70\x48\x59\x73\x00\x00\x01\xbb\x00\x00\x01\xbb\x01\
|
||||
\x3a\xec\xe3\xe2\x00\x00\x00\x19\x74\x45\x58\x74\x53\x6f\x66\x74\
|
||||
\x77\x61\x72\x65\x00\x77\x77\x77\x2e\x69\x6e\x6b\x73\x63\x61\x70\
|
||||
\x65\x2e\x6f\x72\x67\x9b\xee\x3c\x1a\x00\x00\x01\x35\x50\x4c\x54\
|
||||
\x45\xff\xff\xff\x00\x00\x00\x3a\x42\x3a\x00\x00\x00\x2c\x32\x2c\
|
||||
\x00\x00\x00\x20\x20\x20\x00\x00\x00\x15\x15\x12\x00\x00\x00\x05\
|
||||
\x05\x05\x3d\x3e\x3c\x00\x00\x00\x3d\x3e\x3b\x63\x63\x63\x00\x00\
|
||||
\x00\x01\x01\x01\x30\x31\x2f\x02\x02\x02\x24\x25\x24\x02\x02\x02\
|
||||
\x18\x18\x17\x04\x04\x04\x0d\x0d\x0d\x01\x01\x01\x02\x02\x02\x04\
|
||||
\x04\x04\x05\x05\x05\x06\x06\x06\x07\x07\x07\x08\x08\x08\x0c\x0c\
|
||||
\x0c\x0d\x0d\x0d\x10\x10\x10\x14\x14\x13\x14\x14\x14\x19\x19\x19\
|
||||
\x20\x20\x20\x21\x22\x21\x22\x22\x22\x27\x27\x26\x2f\x30\x2e\x31\
|
||||
\x31\x31\x32\x33\x31\x37\x37\x37\x3a\x3a\x3a\x3d\x3e\x3b\x3f\x3f\
|
||||
\x3f\x41\x41\x41\x41\x42\x3f\x44\x45\x43\x45\x45\x45\x47\x47\x47\
|
||||
\x4a\x4a\x4a\x4a\x4b\x48\x4b\x4b\x4b\x4d\x4e\x4b\x4e\x4e\x4e\x4e\
|
||||
\x4f\x4d\x50\x50\x50\x53\x53\x53\x54\x54\x54\x56\x56\x55\x56\x57\
|
||||
\x54\x58\x59\x56\x59\x59\x59\x5b\x5b\x5b\x64\x64\x63\x64\x66\x62\
|
||||
\x66\x68\x64\x68\x68\x68\x6a\x6a\x6a\x6a\x6b\x67\x71\x71\x71\x75\
|
||||
\x75\x75\x79\x79\x79\x7a\x7a\x7a\x84\x84\x84\x86\x86\x86\x8a\x8a\
|
||||
\x8a\x90\x90\x90\x9f\x9f\x9f\xac\xac\xac\xae\xae\xae\xb2\xb2\xb1\
|
||||
\xb7\xb8\xb7\xc1\xc1\xc1\xc4\xc5\xc4\xc6\xc6\xc6\xcf\xd0\xcf\xd4\
|
||||
\xd4\xd4\xde\xde\xde\xe1\xe1\xe1\xe7\xe7\xe7\xe9\xe9\xe9\xea\xea\
|
||||
\xea\xed\xed\xed\xf0\xf0\xf0\xf3\xf3\xf3\xf4\xf4\xf4\xfa\xfa\xfa\
|
||||
\xfb\xfb\xfb\xfc\xfc\xfc\x75\x4a\xf7\xaa\x00\x00\x00\x18\x74\x52\
|
||||
\x4e\x53\x00\x1f\x1f\x2e\x2e\x3f\x3f\x54\x54\x65\x65\xb8\xca\xca\
|
||||
\xd4\xe5\xe5\xe5\xf0\xf0\xf8\xf8\xfd\xfd\x0a\xa9\xac\x9a\x00\x00\
|
||||
\x00\x9d\x49\x44\x41\x54\x18\x19\x9d\xc1\x03\x16\x02\x01\x00\x05\
|
||||
\xc0\x9f\x6d\xdb\xb6\x6d\xdb\x76\x5b\x7b\xff\x23\x84\x3d\x40\xef\
|
||||
\x35\x03\xfc\x89\x2e\x0a\x53\x04\xf8\x62\xca\xea\xe3\x41\xbf\x37\
|
||||
\xec\xb4\x7d\xf8\x60\x2b\x8a\x33\x62\x52\x1f\x11\xf3\xa2\x1b\x6f\
|
||||
\x5c\x55\xaa\xb6\x7f\xdc\x17\x04\x79\xc9\xd9\x01\xf0\x35\xd1\x4c\
|
||||
\xb2\x74\x78\x3c\xc9\x5b\x21\x62\x04\x20\xf1\x47\x42\xc1\xe0\x94\
|
||||
\x24\x9f\x53\x8f\x53\x0b\x80\xa7\xb6\x58\x6d\x89\xc3\xf5\x74\x3d\
|
||||
\xe6\x74\x3a\xbc\x71\x94\x06\xfd\xf6\xbc\x29\xaf\xcf\x3b\x97\x1e\
|
||||
\x1f\x2c\xb9\x23\xbe\xcc\xc7\x2a\xab\x46\xc0\x80\x2f\x86\xd4\x9b\
|
||||
\xae\x36\xbb\xad\x6a\xd6\x04\x0a\x4d\x68\xa6\x88\xf1\xdb\x0b\x5c\
|
||||
\x72\x1c\x18\xbd\x2b\x0f\x2f\x00\x00\x00\x00\x49\x45\x4e\x44\xae\
|
||||
\x42\x60\x82\
|
||||
\x00\x00\x02\xd2\
|
||||
\x89\
|
||||
\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\
|
||||
\x00\x00\x10\x00\x00\x00\x10\x08\x06\x00\x00\x00\x1f\xf3\xff\x61\
|
||||
\x00\x00\x00\x04\x73\x42\x49\x54\x08\x08\x08\x08\x7c\x08\x64\x88\
|
||||
\x00\x00\x00\x09\x70\x48\x59\x73\x00\x00\x01\xbb\x00\x00\x01\xbb\
|
||||
\x01\x3a\xec\xe3\xe2\x00\x00\x00\x19\x74\x45\x58\x74\x53\x6f\x66\
|
||||
\x74\x77\x61\x72\x65\x00\x77\x77\x77\x2e\x69\x6e\x6b\x73\x63\x61\
|
||||
\x70\x65\x2e\x6f\x72\x67\x9b\xee\x3c\x1a\x00\x00\x02\x4f\x49\x44\
|
||||
\x41\x54\x78\xda\xa5\x93\xcb\x4f\x13\x51\x14\x87\xbf\x3b\x33\x1d\
|
||||
\x5a\x5b\x0c\x19\xc0\x42\xa0\xe5\x61\x13\x17\x24\xa8\x71\x65\x8c\
|
||||
\x1b\x8d\x89\x3b\x57\xee\x64\xa7\x0b\x1f\x7b\x48\x7c\x9b\xe0\x42\
|
||||
\x4d\x8c\x8f\x3f\x42\x57\x2e\x5d\x68\x74\x61\x0a\xa8\x41\x40\x5d\
|
||||
\xb0\xd0\x50\x1e\xa2\xb5\x0d\x8f\x4e\xa1\x32\x33\x9d\xeb\x1d\x26\
|
||||
\x4e\x0a\x5b\x4f\x72\x72\xef\xe6\xfb\xf2\x3b\x77\xce\x08\x29\x25\
|
||||
\xff\x53\x06\xbb\x6a\x4e\x88\xc1\x55\x78\x66\xe6\x72\xc9\xa6\x5c\
|
||||
\x2e\x16\x4b\xa7\x75\xb7\x58\xac\x3b\xb3\xb3\xf6\x9e\x42\xe1\x6c\
|
||||
\x9f\x94\x9f\x77\x08\x76\xc3\xa5\x6c\x36\xdf\x79\x77\x34\xd5\x64\
|
||||
\x59\x08\xa1\x81\xa6\x21\x3d\x17\xa7\x62\x77\x2e\x0f\x0f\xe7\x11\
|
||||
\xe2\x58\xa3\x24\x18\x21\x82\x17\xbb\xbb\xf2\x3d\x37\x6e\xa6\xcc\
|
||||
\x8d\x2a\xb2\x5e\x07\xcf\xc3\x57\xa7\xef\xba\xd4\x7d\x1f\x69\xb5\
|
||||
\xb2\x74\xff\x5e\x35\xf3\x63\x39\x92\x68\xff\xe0\xb9\x8e\xf4\x58\
|
||||
\xcf\xed\x5b\x29\xbd\x5c\x42\x28\x48\x57\x2d\x2a\x15\x74\xd5\x86\
|
||||
\x82\x0d\x29\x91\xdf\xbf\x91\x1d\x19\x4e\x15\x3a\x3a\xc6\x02\x86\
|
||||
\x48\x60\x18\xcf\x7b\xaf\x5f\x4d\x6a\xf3\x0b\xe8\xbe\x4f\xdb\xb9\
|
||||
\x21\x5a\x87\x86\xd4\x3d\x10\x79\xb4\x9f\xbf\x40\xe7\xc5\x4b\x98\
|
||||
\x02\xdc\xc9\x49\x7a\xaf\x8d\x24\x03\x26\x7a\x83\x9a\xe7\x25\xaa\
|
||||
\x1f\x26\x68\x69\x69\x43\x98\x26\x38\x0e\x46\x26\x83\x75\xf9\x0a\
|
||||
\xc1\x88\x31\x75\x77\x0b\x73\xe8\xab\xab\x18\x2a\xd1\xc6\xfb\x89\
|
||||
\x6d\x26\x4a\xe0\x80\x60\xb3\x8a\x56\x59\x47\x2f\xfe\x62\x65\xf4\
|
||||
\x0e\xee\xc2\x3c\x46\x77\x46\xc1\x59\xdc\xc5\x05\xd6\x9f\x3c\x26\
|
||||
\xae\x44\xcd\x03\x03\x18\xba\xd8\x66\xa2\x04\x1e\x88\x95\xfc\x5b\
|
||||
\x9a\x8c\x66\xea\xc9\x24\x7a\x36\x1b\x3e\x22\x61\x49\xd7\x65\x63\
|
||||
\xfa\x13\xde\xf4\x14\x75\xdb\x66\x2d\x11\x32\x8d\x09\x90\x9b\x36\
|
||||
\xfc\x5c\xc6\x5d\x5f\xa3\xfd\xc1\x43\xcc\xbe\x7e\xfe\x7c\xfd\xb2\
|
||||
\xdd\x66\xff\x7e\xd2\x8f\x9e\xe2\x27\xe2\x88\x00\xd2\x43\x26\x4a\
|
||||
\x20\x61\xab\xa6\xb3\xa3\xb6\x14\xb8\x78\xfa\x24\xbe\xef\xd3\xf3\
|
||||
\xf2\x35\x9a\x69\x22\x01\x01\x54\xf4\x90\x89\xf6\x60\x4a\x88\x83\
|
||||
\xef\x62\x8c\x0f\x36\x93\xe8\xb2\x41\xdb\xd7\x1e\xda\x83\x4f\x0a\
|
||||
\xb8\x96\x05\x7a\x0c\x7e\x17\x59\x4a\xc1\x8c\x4d\xed\xb8\xcb\xd1\
|
||||
\xc3\x52\xce\x44\x8b\x14\x48\xde\x98\x8c\x1f\xd9\x4b\x22\x53\x21\
|
||||
\x8c\x2a\xc2\x53\x02\xbe\x84\xa5\x16\xc1\xc7\x35\x59\x3b\xe1\x84\
|
||||
\x70\xe3\x26\x46\x92\x57\x4a\x72\xc0\x57\x49\x52\x49\x62\xf1\x38\
|
||||
\xba\x61\x50\xf7\x3c\xca\x08\x26\x57\xca\xb5\x53\x0d\xf0\x6e\x41\
|
||||
\x24\x19\x87\x17\xea\x27\x4a\xc4\x2d\x4b\x0b\x66\xf7\x1d\x07\xaf\
|
||||
\x54\xaa\x1d\x2a\x97\xcf\x44\x70\xa3\xe0\x7f\xea\x2f\xb2\x2a\x1f\
|
||||
\x46\x55\x40\xa7\x1e\x00\x00\x00\x00\x49\x45\x4e\x44\xae\x42\x60\
|
||||
\x82\
|
||||
\x00\x00\x03\x60\
|
||||
\x89\
|
||||
\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\
|
||||
\x00\x00\x10\x00\x00\x00\x10\x08\x06\x00\x00\x00\x1f\xf3\xff\x61\
|
||||
\x00\x00\x00\x06\x62\x4b\x47\x44\x00\xff\x00\xff\x00\xff\xa0\xbd\
|
||||
\xa7\x93\x00\x00\x00\x09\x70\x48\x59\x73\x00\x00\x37\x5c\x00\x00\
|
||||
\x37\x5c\x01\xcb\xc7\xa4\xb9\x00\x00\x02\xd2\x49\x44\x41\x54\x78\
|
||||
\xda\x95\x8e\x4d\x68\x9c\x45\x18\xc7\xff\xcf\xcc\xbc\xef\xec\xbb\
|
||||
\xbb\x6f\xb2\xd9\xb4\x5b\x63\x3e\x68\x44\x5b\xac\x60\xab\xb4\xc5\
|
||||
\x16\x3f\xa8\xe2\x41\x05\xaf\x16\xf1\xe3\xa0\x50\xf0\xd0\x5e\xea\
|
||||
\xcd\x83\x17\x4f\x1e\x14\x0a\x82\x57\xd1\x8b\xe2\x51\x2f\xf5\x20\
|
||||
\x88\x88\xa0\xd2\x58\x9b\x8a\xa9\x36\x9a\xa4\xc9\xa6\x26\xdb\xcd\
|
||||
\xbb\xbb\xef\xee\xbe\x33\xcf\xe3\xec\xc5\xe6\x24\xf5\xf7\xe7\xcf\
|
||||
\xcc\x30\xcc\x6f\x1e\x7a\xe2\xed\xeb\x38\x34\x13\xe9\x6a\xd9\xa0\
|
||||
\xd7\x6a\xd3\x2c\x7a\xfe\x85\xd3\x47\xe4\xfc\x1b\x1f\xce\x4f\xcf\
|
||||
\x34\x0e\x5f\x5f\x69\x15\x57\xae\xae\xfe\x38\xd1\xd8\xbf\x51\x29\
|
||||
\x0d\xd4\xd2\xcf\x8b\x6c\x93\x32\x00\x82\x2b\x0a\x10\x02\xaf\x9f\
|
||||
\xf9\x08\x14\xf2\xfb\x6f\xeb\x70\xec\xd2\xa7\x9f\x3d\xf6\x6e\x3a\
|
||||
\x51\x79\xf9\xd2\x2f\xeb\xe5\x5e\x5e\x40\x11\x5a\x59\x77\xf8\xde\
|
||||
\x17\x9f\xbc\xf2\xce\x85\x6f\x0b\x2c\x5e\x5e\x21\xd6\x31\x56\xb7\
|
||||
\xbc\x1f\x4d\xa0\xef\x9b\x32\x67\x6c\xa4\xa6\x07\x03\x97\x25\xcb\
|
||||
\x0b\xcf\x1d\x3d\x3a\xf7\x68\x65\x72\x8c\x3f\xfb\x72\x11\x36\xd6\
|
||||
\xd4\x5c\xdb\xe6\xf1\x34\xd1\x1b\xcb\xcd\x0b\xc7\x9f\x7c\xe8\x6c\
|
||||
\xe1\x98\xde\x7f\xf3\x84\xd4\xc7\x5f\x83\xb6\x87\xcf\xd6\x4f\x1c\
|
||||
\x88\x3f\x7d\xf0\x9e\xe4\x99\x41\x73\xfd\xa9\xd4\xf8\xb9\x63\x27\
|
||||
\xef\xe5\x5b\x03\x56\x9b\xb9\x57\x0b\xd7\x6e\xd2\xca\xcd\x0e\xda\
|
||||
\x9d\x42\x14\xf0\x30\xaa\xf5\x7a\x32\x7f\xe0\x91\xcf\xbf\xdb\x3e\
|
||||
\xd2\x38\x79\xea\x27\xa3\x15\x81\x45\x3c\x33\xe3\xf2\x0f\x4b\xae\
|
||||
\x3e\x51\xd2\x03\x26\x6d\xcb\xb1\x24\xd5\x18\x79\xc9\x0a\x8d\x57\
|
||||
\x15\x84\x65\xfa\xee\xbd\x26\xb5\xfe\xdc\x03\x33\x4a\xfd\xb9\xae\
|
||||
\x36\x2f\x2d\x17\x1f\x9b\x5a\x19\xba\x3f\x64\xd3\xea\x14\xd8\xe9\
|
||||
\x0c\xf5\x52\x33\x53\x07\x7f\x6d\xe2\x96\x13\xfa\xa3\x5b\x20\xbd\
|
||||
\xab\x46\x7d\x21\x89\x85\x29\x2e\xc5\xe8\x65\x5d\x37\x74\x4e\x8d\
|
||||
\x3e\x4d\x62\x68\x55\x29\x95\x7c\x5e\xb0\xb4\x07\x82\x28\x29\x21\
|
||||
\xeb\xe4\xf8\xfa\xea\x26\x56\xc2\x39\xdd\x57\x83\xab\x55\x10\x4f\
|
||||
\x56\x08\x5a\xf0\xfd\x37\x57\x48\xb4\xd1\xad\x1e\xa3\x37\x64\x5d\
|
||||
\xb6\xd6\xeb\xf9\x53\x2f\xbd\x05\xf1\x8f\x6f\x65\x83\xd8\x69\x83\
|
||||
\xc8\x5a\xb2\x13\x63\x98\x4c\x2b\x38\xb8\x27\x05\x39\x42\x04\x85\
|
||||
\x88\xc3\x1a\x59\x54\xa6\xf6\xa1\xd5\xf7\xd4\xcd\x0b\x08\x67\x9a\
|
||||
\x5e\xfd\xe0\x5a\xf7\xfe\xd9\xf1\x78\xe8\xd8\x04\xb9\x28\x02\xb9\
|
||||
\xc2\x43\x00\xe8\x70\x88\x34\xc1\x79\x09\xe5\x20\x8f\xc0\x9e\x25\
|
||||
\x94\x8c\x56\xb2\xb6\xd5\xe9\x9b\x9e\xb3\xab\x37\x32\x3b\xc7\xcc\
|
||||
\x06\x01\x11\x81\x30\x01\x44\x28\x59\x0d\xcf\x82\x22\x08\x21\x1a\
|
||||
\xd4\x55\x20\xd2\x18\xa1\x94\xe2\x8d\x9d\x7c\xcd\xd4\xaa\x51\x3e\
|
||||
\x55\x37\xc6\x7b\x06\x11\x61\x84\x8c\x22\x08\x65\x00\x0a\x8a\xcc\
|
||||
\xbf\x77\x80\x84\x40\x54\x30\xe5\xfd\x38\x37\x63\xe5\xa8\xdd\xa8\
|
||||
\x69\xed\x99\x04\xbb\xa0\x10\xdc\x7e\x03\x09\xd9\xcd\x48\xf8\x77\
|
||||
\xdb\xb4\x4d\x60\x3b\xb1\x20\x02\x79\xc1\x7f\x41\xbb\x77\xe2\x19\
|
||||
\xc6\x68\xd3\x32\x73\x8d\xa4\x43\xda\x40\x04\x04\x40\xe1\x0e\x10\
|
||||
\xc0\x13\x01\xb3\x7b\xd5\x8e\x71\x7f\x7d\x75\x71\x71\x21\x9b\x75\
|
||||
\xce\x0d\x29\x70\x47\x82\x40\x98\xdc\xee\xa9\xa5\x17\x71\xe8\xb1\
|
||||
\x17\x11\x88\x42\xed\xff\x6c\x74\xfc\xf9\x73\xf8\x07\x10\x7f\x4e\
|
||||
\xbe\xda\xd6\x75\xe4\x00\x00\x00\x22\x7a\x54\x58\x74\x53\x6f\x66\
|
||||
\x74\x77\x61\x72\x65\x00\x00\x78\xda\x2b\x2f\x2f\xd7\xcb\xcc\xcb\
|
||||
\x2e\x4e\x4e\x2c\x48\xd5\xcb\x2f\x4a\x07\x00\x36\xd8\x06\x58\x10\
|
||||
\x53\xca\x5c\x00\x00\x00\x00\x49\x45\x4e\x44\xae\x42\x60\x82\
|
||||
\x00\x00\x02\xac\
|
||||
\x89\
|
||||
\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\
|
||||
\x00\x00\x10\x00\x00\x00\x10\x08\x06\x00\x00\x00\x1f\xf3\xff\x61\
|
||||
\x00\x00\x00\x04\x73\x42\x49\x54\x08\x08\x08\x08\x7c\x08\x64\x88\
|
||||
\x00\x00\x00\x09\x70\x48\x59\x73\x00\x00\x01\xbb\x00\x00\x01\xbb\
|
||||
\x01\x3a\xec\xe3\xe2\x00\x00\x00\x19\x74\x45\x58\x74\x53\x6f\x66\
|
||||
\x74\x77\x61\x72\x65\x00\x77\x77\x77\x2e\x69\x6e\x6b\x73\x63\x61\
|
||||
\x70\x65\x2e\x6f\x72\x67\x9b\xee\x3c\x1a\x00\x00\x02\x29\x49\x44\
|
||||
\x41\x54\x78\xda\x8d\x91\xbf\x4f\x13\x61\x1c\x87\x9f\xf7\xee\xfd\
|
||||
\xd1\x16\x28\xad\x80\x0a\x8b\x89\xc1\x84\x41\x42\xc2\xe0\x64\xa2\
|
||||
\xa6\xea\xe0\x22\x8b\x83\xc1\xc4\x18\xff\x01\x17\x9d\x8c\x8b\x31\
|
||||
\x2e\x0c\x26\x0e\x2c\x98\xe8\x3f\x60\x5c\x4c\x1c\x30\xda\xd9\x01\
|
||||
\x13\x14\xc2\x20\x1a\xa0\x44\x0c\xa5\xa5\x42\xef\xa0\x77\xf7\x7a\
|
||||
\xb4\x56\x21\x5c\xa2\xcf\xf2\xe6\xfd\xde\x27\xcf\x7d\xbe\x77\xc2\
|
||||
\x5a\x8b\xe8\x1b\x9e\x1a\xd0\x1b\xb7\x3d\xcf\xa3\x92\x3e\x05\xa7\
|
||||
\xc7\xf9\x27\x7e\xed\xae\x2d\xde\x9f\x90\x34\x89\x06\xcf\x17\x2e\
|
||||
\x72\xef\xc1\x63\xfe\x87\x17\xc5\x15\x9e\x4f\x2f\x8e\x01\xbf\x05\
|
||||
\xeb\x73\xd5\xcf\xf3\xdd\x5c\xbb\x72\x81\xb0\x6f\x94\xcc\xc8\x0d\
|
||||
\x1a\x61\xc4\x6e\x60\x69\xa3\xa5\x13\xdf\x23\x00\xc2\xa0\x81\x6a\
|
||||
\xd4\xfb\x01\x24\x2d\x3e\xe6\x7a\xfb\xaf\x2e\x97\x77\xc8\x9a\x3c\
|
||||
\xe9\xee\x3e\x2e\x0f\xe5\x18\x3d\x99\x25\x08\x2d\xd9\x8c\x4b\x67\
|
||||
\x4a\x32\x35\xbd\xc2\x5c\xa9\x0e\xc0\xcf\xf2\xea\x32\x80\xc3\x3e\
|
||||
\xa2\x20\xc0\x75\x1c\x72\x1d\x9a\x87\xd7\x07\x59\x58\xf5\x78\xfa\
|
||||
\xa6\xc4\xa3\x97\x4b\x7c\xfd\xe1\xf3\xe4\xd6\x10\x19\xa3\x30\x4a\
|
||||
\xa2\x94\xe2\xb0\x20\x0a\x71\x5d\x97\xb1\x33\xc7\xc8\x68\x27\x0e\
|
||||
\xba\x18\xad\xd0\x71\xf8\xd5\x87\x0a\xc7\x73\x9a\x4b\x23\x3d\xcd\
|
||||
\xbb\x54\x1a\x00\xc9\x3e\xac\xb5\xc8\xb8\xc1\xeb\x99\x2a\xbd\x5d\
|
||||
\x9a\xd9\x25\x3f\x3e\x0d\x35\x2f\xa4\x30\x9c\x07\x01\x4b\xeb\x41\
|
||||
\xab\x81\x4c\x10\x80\x8d\x1b\x38\x04\x91\xcb\xb3\xf7\x65\x00\x8c\
|
||||
\x74\xe8\xe9\x92\xdc\x3c\x77\x34\x5e\x67\x8d\xb5\x5a\x44\x4a\xef\
|
||||
\x35\x50\x87\x05\x0e\x20\xa5\x4b\x26\xa5\xd9\xcf\xf8\xd9\x3c\xd3\
|
||||
\x9f\xb6\x78\x37\xef\x35\x9f\x09\x21\x50\xda\x24\x08\x9c\xbd\xbd\
|
||||
\x35\x9d\xe9\x14\x6d\x3a\x8d\xc3\xc0\x11\xc3\xe4\xdb\x2a\xd9\x78\
|
||||
\x1e\x01\x02\xd0\x09\x82\x66\xad\x5c\x3e\x4f\x47\xda\xd0\xe6\x44\
|
||||
\xaf\x64\xb6\x14\xc6\x6f\x4e\x01\x96\xc8\x5a\x40\xa0\x75\xc2\x37\
|
||||
\x50\xae\x24\x1d\x07\x33\xc6\xfc\x9d\x49\x87\x95\x8a\x25\xa5\x35\
|
||||
\xae\xd8\x13\x08\x2c\x16\xa5\x92\x1a\x48\x89\x63\x2d\x69\xa3\x69\
|
||||
\xd3\x88\xc0\x0a\x68\x97\x12\xc2\x36\x07\x2a\xa9\x81\x2b\x5d\x7c\
|
||||
\xbf\x8e\x8c\x4f\x80\x0e\x03\x77\x0a\x82\x8d\x6d\x98\x2c\xda\x96\
|
||||
\xe0\x4f\x36\xe1\x2f\x20\x1c\xfc\x1d\x9f\x9d\xdd\x46\x2b\x04\x94\
|
||||
\x2a\x2a\x5e\x21\x8a\x67\xe1\xc1\xa8\x70\x0f\x08\xbe\x6d\xd5\xaa\
|
||||
\x78\xdb\x9b\x94\x37\x36\x59\xf8\xb2\x48\x9b\x99\x79\x0e\xb1\x1b\
|
||||
\x06\xd4\x3d\xef\x3b\xc0\x2f\xbb\xd9\xb9\x56\x43\x7d\x15\xe6\x00\
|
||||
\x00\x00\x00\x49\x45\x4e\x44\xae\x42\x60\x82\
|
||||
\x00\x00\x03\xc9\
|
||||
\x89\
|
||||
\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\
|
||||
\x00\x00\x10\x00\x00\x00\x10\x08\x06\x00\x00\x00\x1f\xf3\xff\x61\
|
||||
\x00\x00\x00\x04\x73\x42\x49\x54\x08\x08\x08\x08\x7c\x08\x64\x88\
|
||||
\x00\x00\x00\x09\x70\x48\x59\x73\x00\x00\x01\xbb\x00\x00\x01\xbb\
|
||||
\x01\x3a\xec\xe3\xe2\x00\x00\x00\x19\x74\x45\x58\x74\x53\x6f\x66\
|
||||
\x74\x77\x61\x72\x65\x00\x77\x77\x77\x2e\x69\x6e\x6b\x73\x63\x61\
|
||||
\x70\x65\x2e\x6f\x72\x67\x9b\xee\x3c\x1a\x00\x00\x03\x46\x49\x44\
|
||||
\x41\x54\x38\x8d\x65\x93\xcd\x6f\x14\x65\x00\xc6\x7f\xef\xbc\x3b\
|
||||
\x3b\x3b\xfb\xc5\x2e\xb6\x9b\x52\x1a\x96\xd2\x8a\x21\x6d\x15\xaa\
|
||||
\x50\xa3\x05\x8c\x36\x0a\x18\x48\x8c\x9a\x18\x0f\x8d\x1a\x0f\x06\
|
||||
\x13\x0f\x22\xff\x00\x1c\x4c\x4c\x53\xc3\xc1\x8f\x83\x21\x42\x68\
|
||||
\x24\x22\x1c\xa8\x58\x35\x46\x43\x53\xb5\x40\xd3\x4a\x0c\x69\x89\
|
||||
\xb6\x29\x6c\x69\xd3\xee\x47\x3f\x76\x67\x66\x77\x76\x66\x5f\x4f\
|
||||
\x36\x88\xcf\xf9\xc9\xef\xf2\x3c\x3f\xa1\x94\xe2\x81\xe8\xfd\xa7\
|
||||
\xae\x1a\x93\xb7\x17\x9f\x72\x9c\x6a\x97\x6d\xbb\xde\xf8\xc4\xdc\
|
||||
\x4f\x96\xed\xde\xcc\xce\x9d\x74\x1f\x2c\x8b\xfb\x00\x72\xea\xf6\
|
||||
\x52\xec\xcc\xc0\x8d\xbe\x68\x24\xd8\xeb\xd5\x94\x9e\xc9\x5a\x8c\
|
||||
\xdc\xc8\xe0\xd8\x2e\x9e\xed\x96\xdd\x92\x73\x02\xc5\x47\xd9\xb9\
|
||||
\x93\xfe\xff\x00\x4f\x3c\xdd\xdf\x74\xe4\xc5\xf6\x61\x11\x90\xcd\
|
||||
\x8e\x61\xb0\xaa\x69\xcc\xe6\xcb\x48\xdf\xa7\x58\xb0\x58\x59\x5a\
|
||||
\xa3\x94\x2d\x52\x5e\x2e\x5d\x2b\x17\xac\x97\xb2\x99\x13\x0b\x00\
|
||||
\x81\x7f\x49\xcf\xec\x6d\xbd\x8c\xa1\x37\x97\x13\x31\xc2\x5b\xeb\
|
||||
\x71\x35\x49\x2a\x6f\xe3\xaf\xd9\x6c\x4f\x87\x99\x9a\x09\x51\x4c\
|
||||
\x44\x28\xaf\x94\xba\xec\x5c\xf1\x4b\xe0\x05\x00\x0d\xe0\xb9\x83\
|
||||
\x9f\xbd\x1f\x8e\x9b\xbb\x2a\x51\x13\xbd\x21\xc9\x72\x2c\xca\xa2\
|
||||
\x34\xb0\x0d\x83\x57\x9a\x0a\xbc\xdd\xbd\x91\x37\xf7\x47\x29\xeb\
|
||||
\x92\xb2\x26\xf1\x0d\xfd\xf9\xc7\x7b\x3e\x3d\xba\x0e\x50\x4a\xbd\
|
||||
\xa5\x4c\x83\xbc\x2f\x98\x29\x56\xb9\x97\xb3\xf1\x1c\x97\x87\x8a\
|
||||
\x19\xda\x5a\xb6\xe0\x54\x3c\x3e\x3c\x7d\x19\x19\x0a\x12\x08\x07\
|
||||
\x09\x45\x43\x6c\x4e\x27\x8f\x02\x52\x7e\xf2\x85\x1f\x74\xd1\xfa\
|
||||
\xdc\xa8\x29\xcb\x86\x41\x09\x0d\x21\x04\xca\xab\xd1\x9a\x9f\xa0\
|
||||
\x65\x73\x8a\x64\x62\x03\xb6\x2f\xd8\x12\x5a\x65\xa6\x60\xd0\xb9\
|
||||
\xbd\x8e\x7c\xde\x4a\xae\x2e\x5b\xfd\x32\x1c\xdf\xd7\x11\xab\x8f\
|
||||
\xbd\x6b\xc9\x00\x89\xfa\x18\x15\x25\x40\x00\x5e\x95\x03\x8d\x3e\
|
||||
\xe7\xcf\x0f\x50\x75\x3d\x52\x11\xf8\xfe\xea\x38\x76\x30\x4d\x3e\
|
||||
\x67\xe1\x58\x15\xf9\xfb\xe8\xec\xc5\x00\xb0\xe8\x2b\x85\xf4\x6b\
|
||||
\xd4\x5c\x8f\xaa\x5f\x26\x20\x7c\x8e\x34\xdc\x63\xfa\xaf\x39\x82\
|
||||
\x41\x93\xdf\xae\x8f\x73\x6b\x36\x47\xac\xe3\x75\xf4\x95\x0a\xe5\
|
||||
\x8a\x47\x50\x13\x58\x4e\x75\x41\x28\xa5\x78\xe4\xc9\x8f\xe7\x65\
|
||||
\x6a\xc3\xa6\x64\xd3\x46\xea\x53\x11\x0e\x6f\x5b\xe4\xe7\x1f\xbe\
|
||||
\xc3\x4c\x34\x30\x56\x6a\x24\x5c\xb7\x0d\x21\x4c\x22\x02\x7c\xc7\
|
||||
\x45\x54\x5c\xe6\xee\xe4\x17\xa6\x7e\x7c\xa7\x51\x03\x90\x1a\x23\
|
||||
\xca\xa9\xa2\x1c\x8b\x43\x4d\x77\xb9\xf4\xf5\x57\xa4\x1a\xb7\x72\
|
||||
\xb3\xb6\x93\x58\x43\x07\x42\x85\x50\xae\x47\x22\x24\x89\x85\x24\
|
||||
\xf3\x8b\x45\x6a\xbe\x1a\x5e\x5f\xa1\xb0\x54\x3c\xd6\xb8\xc9\x28\
|
||||
\xbd\xd6\x59\x60\xe0\xdc\x19\x76\x76\xee\xe1\x97\xf9\x26\xa4\x4c\
|
||||
\x10\xf4\x7d\x52\x66\x80\x96\xfa\x30\xb9\x6c\x89\xbf\x67\x72\x08\
|
||||
\x4d\x5b\xf3\x2b\xd5\xe3\xeb\x47\xfa\xbc\xef\xd1\xd8\xe4\xe4\x64\
|
||||
\xe4\xec\xd9\x6f\x38\x70\xf0\x30\xc3\xd3\x09\xda\x5b\x5a\x59\xb3\
|
||||
\xaa\xe8\x52\xb0\xba\x62\x31\x93\xb7\x30\x0c\x1d\x2d\x1a\xc6\x5b\
|
||||
\x2e\x1d\x9b\x1e\x79\x2f\x03\x20\xdb\xda\xda\x76\x58\x96\xf5\xeb\
|
||||
\x95\x2b\xdf\x9a\xfb\xf6\xee\xf7\x87\x33\x75\x56\xfc\xe1\xc7\x0c\
|
||||
\x57\x68\x24\x92\x26\x79\xdb\x67\xb5\x26\xd0\x93\x71\x64\x48\xcf\
|
||||
\xfb\x6b\xf6\x1b\x7f\x5e\xec\x3d\xb7\x2e\x50\x3a\x9d\x3e\x1e\x8f\
|
||||
\xc7\x2f\xec\xde\xbd\xe7\xd9\xc1\xc1\xc1\x97\xa7\x67\x9b\x3f\x28\
|
||||
\xd9\x6e\xcd\xae\xa1\x2d\x59\x6e\xac\xe2\xab\x4a\xc2\xd4\x6e\xe9\
|
||||
\xae\x7b\x49\xdd\x5d\x7a\xf5\xfa\x85\xde\xb1\xff\xd8\xd8\xdd\xdd\
|
||||
\xdd\xde\xd3\xd3\x73\x7a\x74\x74\xf4\xd4\xd0\xd0\xd0\x80\x10\x22\
|
||||
\x05\xec\x00\x76\x01\x5d\x40\x1c\xf8\x03\x98\x00\xc6\x80\x3b\xea\
|
||||
\x3e\x85\xff\x01\xeb\xf9\x7f\xc7\xb1\xde\x54\x6d\x00\x00\x00\x00\
|
||||
\x49\x45\x4e\x44\xae\x42\x60\x82\
|
||||
\x00\x00\x03\xb6\
|
||||
\x89\
|
||||
\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\
|
||||
\x00\x00\x10\x00\x00\x00\x10\x08\x06\x00\x00\x00\x1f\xf3\xff\x61\
|
||||
\x00\x00\x00\x09\x70\x48\x59\x73\x00\x00\x37\x5c\x00\x00\x37\x5c\
|
||||
\x01\xcb\xc7\xa4\xb9\x00\x00\x00\x06\x62\x4b\x47\x44\x00\xff\x00\
|
||||
\xff\x00\xff\xa0\xbd\xa7\x93\x00\x00\x03\x28\x49\x44\x41\x54\x78\
|
||||
\xda\x75\x92\x5b\x48\x93\x61\x18\xc7\xff\xdf\x3e\xf2\xd8\xb9\x70\
|
||||
\x98\x41\x75\x63\x45\x46\x84\xdd\x74\x22\x0c\xea\x22\xa2\xc3\x45\
|
||||
\x17\x19\xd9\x41\xd3\x9d\x9c\x3b\x1f\xdc\xd1\x22\x2d\x6d\x6b\xe5\
|
||||
\x37\x91\x8a\x72\xd3\xcd\x39\x4f\xe5\x74\x82\xe6\x66\x90\xb9\x42\
|
||||
\x8b\x0a\x5a\xd8\x61\xe4\x5d\x4a\x12\x23\x3a\xd8\xe1\xed\x5d\x48\
|
||||
\x10\xb1\x1f\xfc\xee\xde\xff\xf3\x3e\xfc\x79\x90\x0c\x8f\xb7\x05\
|
||||
\x07\x0f\x1d\x80\xcb\xd5\x04\xce\x59\xcf\xd8\x2f\xdb\x20\x91\x88\
|
||||
\x37\xf8\xdb\xfd\x8d\x43\x43\x83\xb7\x3c\xde\xe6\x1d\x4f\x9f\x3d\
|
||||
\x41\x52\x9c\x0d\x1c\x14\x4a\x19\xca\x04\x67\x98\xcd\xf9\x9b\xb0\
|
||||
\x73\xd7\x76\x7e\x28\x34\x34\x19\x8f\xc7\x49\x9b\xdf\xf7\xc9\x5a\
|
||||
\x65\x36\xbc\x8d\xbd\x41\x52\xba\xbb\xbb\x50\x2e\x95\xd0\x21\x72\
|
||||
\xb6\xb8\xe4\x14\x84\x22\x41\xf1\xf8\xe3\x31\x32\x35\xf5\xfe\xb3\
|
||||
\xc5\x62\x5e\x5b\x77\xa9\x16\xd7\xae\x5f\x63\xfe\x0b\xce\xcc\x7c\
|
||||
\x40\x38\x1c\x46\xe4\x61\x04\xaf\xdf\x4c\xc0\xd7\xe6\xe5\x95\x9c\
|
||||
\x39\x89\x7a\xee\x4a\x5f\x4f\xe0\x0e\x99\x9e\x9e\x22\xde\x56\x4f\
|
||||
\x51\x30\x18\x44\x8b\xc7\x9d\xfb\x4f\x78\xf8\x5e\x08\x09\x94\x6a\
|
||||
\x15\x0d\xd4\xa3\xa3\xb3\x9d\x9d\x98\x78\x89\x47\x8f\x22\x9b\x9a\
|
||||
\x5b\xdc\xdf\x04\x62\xf1\x8f\x50\x38\xf4\xab\xb3\xab\x63\xe6\xf6\
|
||||
\x9d\xee\x57\x2e\x77\x53\xeb\xdf\x70\x6d\x5d\x0d\x2d\xeb\x0a\x2d\
|
||||
\xcf\x0d\x9b\xfd\x42\xa2\x38\x36\xfa\x32\x8a\xb1\xb1\x31\xfe\x68\
|
||||
\x64\x74\xa4\xcd\xef\x27\x47\x8e\x16\xfe\xe4\x1a\x1a\x7e\x86\xc2\
|
||||
\x43\xc4\x6e\xb7\xbd\x16\x89\x45\xab\x90\x40\xae\xac\x80\x4a\xa3\
|
||||
\x80\x46\xa7\x82\x5c\x21\xc5\xd9\x73\x55\x6c\xa0\x2f\x80\xf0\x70\
|
||||
\x68\xab\x5c\x21\x8f\xe5\x6f\xc9\x27\x03\x83\x03\xd3\xd5\x35\xd5\
|
||||
\xbe\x8b\xb5\x17\x6b\x9c\x4e\xae\x2c\x8b\x9f\x95\x95\x96\x96\x0a\
|
||||
\x58\xaa\x4c\xd0\x1b\xb4\x30\x9a\xf4\x74\x75\x39\x23\x10\x96\xf1\
|
||||
\x8e\x17\x15\xd1\x2d\xea\x04\x87\x0e\x1f\xfc\x92\xbd\x22\x9b\x88\
|
||||
\x25\xe2\x17\x8f\x9f\x8c\xe7\xce\xce\x7e\xc5\x83\xd1\x11\xa6\xbf\
|
||||
\x3f\x88\xc1\xbb\x83\xb0\x5a\xad\x0c\x08\x21\x18\x89\xdc\x87\x5a\
|
||||
\xab\xe4\xd9\x1c\x56\x28\x54\xe5\x69\x6a\x8d\xf2\xc6\x9e\xbd\x7b\
|
||||
\x48\xce\xca\x1c\x42\x07\x8e\xc7\xe3\x1f\xb3\x13\xef\xcc\x56\x2b\
|
||||
\xeb\x6e\x76\x53\x5d\x6c\xde\xc6\x3c\x66\xdb\xb6\xad\xc0\xf1\xa2\
|
||||
\x63\xa8\x34\x6a\x59\xa1\xb8\x14\xa7\x4b\x4e\xac\x91\x2b\x65\x0f\
|
||||
\x0b\x8f\x15\x92\x82\xdd\x05\xf4\x67\xd1\xe8\x8b\xe8\xf3\x65\x84\
|
||||
\x7c\x47\x57\x77\x27\x2f\xd8\xdf\x47\x8b\x1e\xc6\xbb\xc9\x49\x70\
|
||||
\x9c\x03\x7f\x30\x59\x0c\x3c\xa5\x5a\x06\x71\xb9\x70\x9f\x4e\xaf\
|
||||
\x99\x36\x18\x0d\x44\x28\x12\x12\xa5\x5a\x71\xaf\xa7\xb7\x6b\x51\
|
||||
\x6c\x32\x8a\x26\xd7\x4d\xde\x8d\x9b\xd7\x41\x5b\x47\x5b\xbb\x0f\
|
||||
\x81\x9e\x0e\xfc\xa5\xa0\x60\x37\xa3\x50\xc9\x2e\xd0\x43\x21\x15\
|
||||
\xb2\x8a\x59\xa3\xc9\x48\x2a\x8d\xba\xbb\xe7\xce\x9b\xe7\x57\xd7\
|
||||
\xe9\x60\x77\x5c\x62\xec\x0e\x1b\x38\xe7\x55\x7a\x38\x8d\x88\xc5\
|
||||
\xa2\xf8\x07\x5d\xa5\xda\x68\x30\xe9\x34\x15\x32\x69\xa8\xb8\xa4\
|
||||
\x98\x68\xf5\xea\x9e\x52\xc1\xc9\x74\xad\xd4\x0b\x81\xa8\x94\x07\
|
||||
\x4a\x66\x66\x26\x92\x62\xb6\x18\x3c\xad\x3e\xcf\x3c\xbd\x41\xc3\
|
||||
\xe9\xf4\xea\xde\x8f\x5f\x26\x98\x8e\x40\x23\xea\x9d\x0e\x34\xb7\
|
||||
\x34\x25\x4a\xfe\x63\x32\xe8\x06\x9a\xfd\xd4\x5e\x89\x54\x74\x7e\
|
||||
\xf5\x9a\x55\xf3\xd3\xd3\xd3\x17\xa7\xa4\xa6\x2c\x07\xb0\x94\xba\
|
||||
\x84\xba\x88\xba\x80\x9a\x41\x4d\xa3\xa6\x50\x59\x2a\x83\x04\xeb\
|
||||
\xd7\xaf\x43\xee\xda\xdc\x05\xa9\x94\x8c\x8c\x0c\x3e\xcb\xb2\x39\
|
||||
\x00\xb2\xe7\xe4\x53\x97\xcf\x0d\x5a\x48\xcd\x9c\x1b\x32\x8f\xca\
|
||||
\x03\xe5\x37\x40\x64\x67\x7f\x6c\xb6\xdc\xf4\x00\x00\x00\x22\x7a\
|
||||
\x54\x58\x74\x53\x6f\x66\x74\x77\x61\x72\x65\x00\x00\x78\xda\x2b\
|
||||
\x2f\x2f\xd7\xcb\xcc\xcb\x2e\x4e\x4e\x2c\x48\xd5\xcb\x2f\x4a\x07\
|
||||
\x00\x36\xd8\x06\x58\x10\x53\xca\x5c\x00\x00\x00\x00\x49\x45\x4e\
|
||||
\x44\xae\x42\x60\x82\
|
||||
"
|
||||
|
||||
qt_resource_name = "\
|
||||
\x00\x05\
|
||||
\x00\x6f\xa6\x53\
|
||||
\x00\x69\
|
||||
\x00\x63\x00\x6f\x00\x6e\x00\x73\
|
||||
\x00\x0e\
|
||||
\x06\x0c\xe6\x07\
|
||||
\x00\x61\
|
||||
\x00\x72\x00\x72\x00\x6f\x00\x77\x00\x5f\x00\x64\x00\x6f\x00\x77\x00\x6e\x00\x2e\x00\x70\x00\x6e\x00\x67\
|
||||
\x00\x09\
|
||||
\x06\xc7\x98\x67\
|
||||
\x00\x61\
|
||||
\x00\x62\x00\x6f\x00\x75\x00\x74\x00\x2e\x00\x70\x00\x6e\x00\x67\
|
||||
\x00\x08\
|
||||
\x0b\x63\x58\x07\
|
||||
\x00\x73\
|
||||
\x00\x74\x00\x6f\x00\x70\x00\x2e\x00\x70\x00\x6e\x00\x67\
|
||||
\x00\x08\
|
||||
\x0c\xac\x40\xd6\
|
||||
\x00\x62\
|
||||
\x00\x75\x00\x73\x00\x79\x00\x2e\x00\x67\x00\x69\x00\x66\
|
||||
\x00\x08\
|
||||
\x0f\x07\x5a\xc7\
|
||||
\x00\x65\
|
||||
\x00\x78\x00\x69\x00\x74\x00\x2e\x00\x70\x00\x6e\x00\x67\
|
||||
\x00\x07\
|
||||
\x08\x73\x57\x87\
|
||||
\x00\x61\
|
||||
\x00\x70\x00\x70\x00\x2e\x00\x70\x00\x6e\x00\x67\
|
||||
\x00\x09\
|
||||
\x08\x97\xa2\x07\
|
||||
\x00\x73\
|
||||
\x00\x74\x00\x61\x00\x72\x00\x74\x00\x2e\x00\x70\x00\x6e\x00\x67\
|
||||
\x00\x08\
|
||||
\x06\x7c\x5a\x07\
|
||||
\x00\x63\
|
||||
\x00\x6f\x00\x70\x00\x79\x00\x2e\x00\x70\x00\x6e\x00\x67\
|
||||
\x00\x08\
|
||||
\x08\xc8\x58\x67\
|
||||
\x00\x73\
|
||||
\x00\x61\x00\x76\x00\x65\x00\x2e\x00\x70\x00\x6e\x00\x67\
|
||||
\x00\x09\
|
||||
\x0b\x85\x83\x07\
|
||||
\x00\x63\
|
||||
\x00\x6c\x00\x65\x00\x61\x00\x72\x00\x2e\x00\x70\x00\x6e\x00\x67\
|
||||
\x00\x0a\
|
||||
\x09\xb2\x67\xc7\
|
||||
\x00\x63\
|
||||
\x00\x61\x00\x6e\x00\x63\x00\x65\x00\x6c\x00\x2e\x00\x70\x00\x6e\x00\x67\
|
||||
\x00\x0a\
|
||||
\x00\x4a\x9d\x27\
|
||||
\x00\x6f\
|
||||
\x00\x6e\x00\x6c\x00\x69\x00\x6e\x00\x65\x00\x2e\x00\x70\x00\x6e\x00\x67\
|
||||
\x00\x08\
|
||||
\x0c\x33\x5a\x87\
|
||||
\x00\x68\
|
||||
\x00\x65\x00\x6c\x00\x70\x00\x2e\x00\x70\x00\x6e\x00\x67\
|
||||
\x00\x0b\
|
||||
\x06\xba\xa1\x47\
|
||||
\x00\x6f\
|
||||
\x00\x70\x00\x74\x00\x69\x00\x6f\x00\x6e\x00\x73\x00\x2e\x00\x70\x00\x6e\x00\x67\
|
||||
\x00\x0f\
|
||||
\x0e\x5e\x99\xe7\
|
||||
\x00\x70\
|
||||
\x00\x72\x00\x65\x00\x66\x00\x65\x00\x72\x00\x65\x00\x6e\x00\x63\x00\x65\x00\x73\x00\x2e\x00\x70\x00\x6e\x00\x67\
|
||||
"
|
||||
|
||||
qt_resource_struct = "\
|
||||
\x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x01\
|
||||
\x00\x00\x00\x00\x00\x02\x00\x00\x00\x0f\x00\x00\x00\x02\
|
||||
\x00\x00\x01\x16\x00\x00\x00\x00\x00\x01\x00\x00\x20\xac\
|
||||
\x00\x00\x00\x10\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\
|
||||
\x00\x00\x00\xb8\x00\x00\x00\x00\x00\x01\x00\x00\x16\x1a\
|
||||
\x00\x00\x01\x46\x00\x00\x00\x00\x00\x01\x00\x00\x26\xc0\
|
||||
\x00\x00\x00\x32\x00\x00\x00\x00\x00\x01\x00\x00\x01\xc0\
|
||||
\x00\x00\x00\x8c\x00\x00\x00\x00\x00\x01\x00\x00\x0f\xe0\
|
||||
\x00\x00\x00\xa0\x00\x00\x00\x00\x00\x01\x00\x00\x14\x21\
|
||||
\x00\x00\x00\xce\x00\x00\x00\x00\x00\x01\x00\x00\x18\x03\
|
||||
\x00\x00\x00\xfc\x00\x00\x00\x00\x00\x01\x00\x00\x1d\xd6\
|
||||
\x00\x00\x00\x4a\x00\x00\x00\x00\x00\x01\x00\x00\x04\xe7\
|
||||
\x00\x00\x00\xe4\x00\x00\x00\x00\x00\x01\x00\x00\x1b\x4e\
|
||||
\x00\x00\x01\x30\x00\x00\x00\x00\x00\x01\x00\x00\x24\x10\
|
||||
\x00\x00\x00\x60\x00\x00\x00\x00\x00\x01\x00\x00\x06\xde\
|
||||
\x00\x00\x01\x62\x00\x00\x00\x00\x00\x01\x00\x00\x2a\x8d\
|
||||
\x00\x00\x00\x76\x00\x00\x00\x00\x00\x01\x00\x00\x0c\x92\
|
||||
"
|
||||
|
||||
def qInitResources():
|
||||
QtCore.qRegisterResourceData(0x01, qt_resource_struct, qt_resource_name, qt_resource_data)
|
||||
|
||||
def qCleanupResources():
|
||||
QtCore.qUnregisterResourceData(0x01, qt_resource_struct, qt_resource_name, qt_resource_data)
|
||||
|
||||
qInitResources()
|
||||
|
|
@ -1,43 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Form implementation generated from reading ui file 'ui/debug.ui'
|
||||
#
|
||||
# Created: Fri Feb 28 21:24:59 2014
|
||||
# by: PyQt4 UI code generator 4.9.3
|
||||
#
|
||||
# WARNING! All changes made in this file will be lost!
|
||||
|
||||
from PyQt4 import QtCore, QtGui
|
||||
|
||||
try:
|
||||
_fromUtf8 = QtCore.QString.fromUtf8
|
||||
except AttributeError:
|
||||
_fromUtf8 = lambda s: s
|
||||
|
||||
class Ui_DebugDialog(object):
|
||||
def setupUi(self, DebugDialog):
|
||||
DebugDialog.setObjectName(_fromUtf8("DebugDialog"))
|
||||
DebugDialog.setWindowModality(QtCore.Qt.ApplicationModal)
|
||||
DebugDialog.resize(564, 547)
|
||||
self.verticalLayout = QtGui.QVBoxLayout(DebugDialog)
|
||||
self.verticalLayout.setObjectName(_fromUtf8("verticalLayout"))
|
||||
self.frame = QtGui.QFrame(DebugDialog)
|
||||
self.frame.setFrameShape(QtGui.QFrame.StyledPanel)
|
||||
self.frame.setFrameShadow(QtGui.QFrame.Raised)
|
||||
self.frame.setObjectName(_fromUtf8("frame"))
|
||||
self.verticalLayout_2 = QtGui.QVBoxLayout(self.frame)
|
||||
self.verticalLayout_2.setObjectName(_fromUtf8("verticalLayout_2"))
|
||||
self.textEdit = QtGui.QPlainTextEdit(self.frame)
|
||||
self.textEdit.setUndoRedoEnabled(False)
|
||||
self.textEdit.setReadOnly(True)
|
||||
self.textEdit.setPlainText(_fromUtf8(""))
|
||||
self.textEdit.setObjectName(_fromUtf8("textEdit"))
|
||||
self.verticalLayout_2.addWidget(self.textEdit)
|
||||
self.verticalLayout.addWidget(self.frame)
|
||||
|
||||
self.retranslateUi(DebugDialog)
|
||||
QtCore.QMetaObject.connectSlotsByName(DebugDialog)
|
||||
|
||||
def retranslateUi(self, DebugDialog):
|
||||
DebugDialog.setWindowTitle(_("LinkChecker debug log"))
|
||||
|
||||
|
|
@ -1,60 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Form implementation generated from reading ui file 'ui/editor.ui'
|
||||
#
|
||||
# Created: Mon Dec 12 19:00:37 2011
|
||||
# by: PyQt4 UI code generator 4.8.6
|
||||
#
|
||||
# WARNING! All changes made in this file will be lost!
|
||||
|
||||
from PyQt4 import QtCore, QtGui
|
||||
|
||||
try:
|
||||
_fromUtf8 = QtCore.QString.fromUtf8
|
||||
except AttributeError:
|
||||
_fromUtf8 = lambda s: s
|
||||
|
||||
class Ui_EditorDialog(object):
|
||||
def setupUi(self, EditorDialog):
|
||||
EditorDialog.setObjectName(_fromUtf8("EditorDialog"))
|
||||
EditorDialog.setWindowModality(QtCore.Qt.ApplicationModal)
|
||||
EditorDialog.resize(640, 600)
|
||||
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Preferred)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(EditorDialog.sizePolicy().hasHeightForWidth())
|
||||
EditorDialog.setSizePolicy(sizePolicy)
|
||||
EditorDialog.setWindowTitle(_("LinkChecker source view"))
|
||||
self.verticalLayout = QtGui.QVBoxLayout(EditorDialog)
|
||||
self.verticalLayout.setMargin(0)
|
||||
self.verticalLayout.setObjectName(_fromUtf8("verticalLayout"))
|
||||
self.menubar = QtGui.QMenuBar(EditorDialog)
|
||||
self.menubar.setObjectName(_fromUtf8("menubar"))
|
||||
self.menuFile = QtGui.QMenu(self.menubar)
|
||||
self.menuFile.setTitle(_("&File"))
|
||||
self.menuFile.setObjectName(_fromUtf8("menuFile"))
|
||||
self.verticalLayout.addWidget(self.menubar)
|
||||
self.frame = QtGui.QFrame(EditorDialog)
|
||||
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.frame.sizePolicy().hasHeightForWidth())
|
||||
self.frame.setSizePolicy(sizePolicy)
|
||||
self.frame.setFrameShape(QtGui.QFrame.NoFrame)
|
||||
self.frame.setFrameShadow(QtGui.QFrame.Plain)
|
||||
self.frame.setLineWidth(0)
|
||||
self.frame.setObjectName(_fromUtf8("frame"))
|
||||
self.verticalLayout.addWidget(self.frame)
|
||||
self.actionSave = QtGui.QAction(EditorDialog)
|
||||
self.actionSave.setText(_("&Save"))
|
||||
self.actionSave.setShortcut(_("Ctrl+S"))
|
||||
self.actionSave.setObjectName(_fromUtf8("actionSave"))
|
||||
self.menuFile.addAction(self.actionSave)
|
||||
self.menubar.addAction(self.menuFile.menuAction())
|
||||
|
||||
self.retranslateUi(EditorDialog)
|
||||
QtCore.QMetaObject.connectSlotsByName(EditorDialog)
|
||||
|
||||
def retranslateUi(self, EditorDialog):
|
||||
pass
|
||||
|
||||
|
|
@ -1,844 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Form implementation generated from reading ui file 'ui/main.ui'
|
||||
#
|
||||
# Created: Fri Feb 28 21:24:58 2014
|
||||
# by: PyQt4 UI code generator 4.9.3
|
||||
#
|
||||
# WARNING! All changes made in this file will be lost!
|
||||
|
||||
from PyQt4 import QtCore, QtGui
|
||||
|
||||
try:
|
||||
_fromUtf8 = QtCore.QString.fromUtf8
|
||||
except AttributeError:
|
||||
_fromUtf8 = lambda s: s
|
||||
|
||||
class Ui_MainWindow(object):
|
||||
def setupUi(self, MainWindow):
|
||||
MainWindow.setObjectName(_fromUtf8("MainWindow"))
|
||||
MainWindow.resize(713, 627)
|
||||
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Preferred)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(MainWindow.sizePolicy().hasHeightForWidth())
|
||||
MainWindow.setSizePolicy(sizePolicy)
|
||||
icon = QtGui.QIcon()
|
||||
icon.addPixmap(QtGui.QPixmap(_fromUtf8(":/icons/app.png")), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
MainWindow.setWindowIcon(icon)
|
||||
MainWindow.setStatusTip(_fromUtf8(""))
|
||||
self.centralwidget = QtGui.QWidget(MainWindow)
|
||||
self.centralwidget.setObjectName(_fromUtf8("centralwidget"))
|
||||
self.verticalLayout = QtGui.QVBoxLayout(self.centralwidget)
|
||||
self.verticalLayout.setMargin(4)
|
||||
self.verticalLayout.setObjectName(_fromUtf8("verticalLayout"))
|
||||
self.horizontalLayout_3 = QtGui.QHBoxLayout()
|
||||
self.horizontalLayout_3.setObjectName(_fromUtf8("horizontalLayout_3"))
|
||||
self.label = QtGui.QLabel(self.centralwidget)
|
||||
self.label.setObjectName(_fromUtf8("label"))
|
||||
self.horizontalLayout_3.addWidget(self.label)
|
||||
spacerItem = QtGui.QSpacerItem(4, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum)
|
||||
self.horizontalLayout_3.addItem(spacerItem)
|
||||
self.urlinput = LineEdit(self.centralwidget)
|
||||
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Fixed)
|
||||
sizePolicy.setHorizontalStretch(1)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.urlinput.sizePolicy().hasHeightForWidth())
|
||||
self.urlinput.setSizePolicy(sizePolicy)
|
||||
self.urlinput.setMaxLength(2048)
|
||||
self.urlinput.setObjectName(_fromUtf8("urlinput"))
|
||||
self.horizontalLayout_3.addWidget(self.urlinput)
|
||||
spacerItem1 = QtGui.QSpacerItem(10, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum)
|
||||
self.horizontalLayout_3.addItem(spacerItem1)
|
||||
self.controlButton = QtGui.QPushButton(self.centralwidget)
|
||||
self.controlButton.setStatusTip(_fromUtf8(""))
|
||||
icon1 = QtGui.QIcon()
|
||||
icon1.addPixmap(QtGui.QPixmap(_fromUtf8(":/icons/start.png")), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
self.controlButton.setIcon(icon1)
|
||||
self.controlButton.setDefault(True)
|
||||
self.controlButton.setObjectName(_fromUtf8("controlButton"))
|
||||
self.horizontalLayout_3.addWidget(self.controlButton)
|
||||
self.verticalLayout.addLayout(self.horizontalLayout_3)
|
||||
self.horizontalLayout_4 = QtGui.QHBoxLayout()
|
||||
self.horizontalLayout_4.setSizeConstraint(QtGui.QLayout.SetDefaultConstraint)
|
||||
self.horizontalLayout_4.setContentsMargins(0, 0, -1, -1)
|
||||
self.horizontalLayout_4.setObjectName(_fromUtf8("horizontalLayout_4"))
|
||||
self.label_29 = QtGui.QLabel(self.centralwidget)
|
||||
self.label_29.setObjectName(_fromUtf8("label_29"))
|
||||
self.horizontalLayout_4.addWidget(self.label_29)
|
||||
self.label_32 = QtGui.QLabel(self.centralwidget)
|
||||
self.label_32.setObjectName(_fromUtf8("label_32"))
|
||||
self.horizontalLayout_4.addWidget(self.label_32)
|
||||
self.label_active = QtGui.QLabel(self.centralwidget)
|
||||
self.label_active.setMinimumSize(QtCore.QSize(40, 0))
|
||||
self.label_active.setObjectName(_fromUtf8("label_active"))
|
||||
self.horizontalLayout_4.addWidget(self.label_active)
|
||||
self.label_30 = QtGui.QLabel(self.centralwidget)
|
||||
self.label_30.setObjectName(_fromUtf8("label_30"))
|
||||
self.horizontalLayout_4.addWidget(self.label_30)
|
||||
self.label_queued = QtGui.QLabel(self.centralwidget)
|
||||
self.label_queued.setMinimumSize(QtCore.QSize(40, 0))
|
||||
self.label_queued.setObjectName(_fromUtf8("label_queued"))
|
||||
self.horizontalLayout_4.addWidget(self.label_queued)
|
||||
self.label_28 = QtGui.QLabel(self.centralwidget)
|
||||
self.label_28.setObjectName(_fromUtf8("label_28"))
|
||||
self.horizontalLayout_4.addWidget(self.label_28)
|
||||
self.label_checked = QtGui.QLabel(self.centralwidget)
|
||||
self.label_checked.setMinimumSize(QtCore.QSize(50, 0))
|
||||
self.label_checked.setObjectName(_fromUtf8("label_checked"))
|
||||
self.horizontalLayout_4.addWidget(self.label_checked)
|
||||
self.label_15 = QtGui.QLabel(self.centralwidget)
|
||||
self.label_15.setObjectName(_fromUtf8("label_15"))
|
||||
self.horizontalLayout_4.addWidget(self.label_15)
|
||||
self.label_busy = QtGui.QLabel(self.centralwidget)
|
||||
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed)
|
||||
sizePolicy.setHorizontalStretch(16)
|
||||
sizePolicy.setVerticalStretch(16)
|
||||
sizePolicy.setHeightForWidth(self.label_busy.sizePolicy().hasHeightForWidth())
|
||||
self.label_busy.setSizePolicy(sizePolicy)
|
||||
self.label_busy.setMinimumSize(QtCore.QSize(16, 16))
|
||||
self.label_busy.setObjectName(_fromUtf8("label_busy"))
|
||||
self.horizontalLayout_4.addWidget(self.label_busy)
|
||||
self.label_status = QtGui.QLabel(self.centralwidget)
|
||||
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.MinimumExpanding, QtGui.QSizePolicy.Preferred)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.label_status.sizePolicy().hasHeightForWidth())
|
||||
self.label_status.setSizePolicy(sizePolicy)
|
||||
self.label_status.setText(_fromUtf8(""))
|
||||
self.label_status.setObjectName(_fromUtf8("label_status"))
|
||||
self.horizontalLayout_4.addWidget(self.label_status)
|
||||
self.verticalLayout.addLayout(self.horizontalLayout_4)
|
||||
self.treeView = QtGui.QTreeView(self.centralwidget)
|
||||
self.treeView.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
|
||||
self.treeView.setEditTriggers(QtGui.QAbstractItemView.NoEditTriggers)
|
||||
self.treeView.setAlternatingRowColors(True)
|
||||
self.treeView.setSelectionMode(QtGui.QAbstractItemView.ExtendedSelection)
|
||||
self.treeView.setRootIsDecorated(False)
|
||||
self.treeView.setUniformRowHeights(True)
|
||||
self.treeView.setItemsExpandable(False)
|
||||
self.treeView.setSortingEnabled(False)
|
||||
self.treeView.setAllColumnsShowFocus(True)
|
||||
self.treeView.setExpandsOnDoubleClick(False)
|
||||
self.treeView.setObjectName(_fromUtf8("treeView"))
|
||||
self.verticalLayout.addWidget(self.treeView)
|
||||
self.horizontalLayout = QtGui.QHBoxLayout()
|
||||
self.horizontalLayout.setObjectName(_fromUtf8("horizontalLayout"))
|
||||
self.url_properties = QtGui.QGroupBox(self.centralwidget)
|
||||
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Expanding)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.url_properties.sizePolicy().hasHeightForWidth())
|
||||
self.url_properties.setSizePolicy(sizePolicy)
|
||||
self.url_properties.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignTop)
|
||||
self.url_properties.setObjectName(_fromUtf8("url_properties"))
|
||||
self.horizontalLayout_2 = QtGui.QHBoxLayout(self.url_properties)
|
||||
self.horizontalLayout_2.setObjectName(_fromUtf8("horizontalLayout_2"))
|
||||
self.frame = QtGui.QFrame(self.url_properties)
|
||||
self.frame.setFrameShape(QtGui.QFrame.NoFrame)
|
||||
self.frame.setFrameShadow(QtGui.QFrame.Plain)
|
||||
self.frame.setLineWidth(0)
|
||||
self.frame.setObjectName(_fromUtf8("frame"))
|
||||
self.formLayout = QtGui.QFormLayout(self.frame)
|
||||
self.formLayout.setFieldGrowthPolicy(QtGui.QFormLayout.ExpandingFieldsGrow)
|
||||
self.formLayout.setObjectName(_fromUtf8("formLayout"))
|
||||
self.label_2 = QtGui.QLabel(self.frame)
|
||||
self.label_2.setObjectName(_fromUtf8("label_2"))
|
||||
self.formLayout.setWidget(0, QtGui.QFormLayout.LabelRole, self.label_2)
|
||||
self.prop_url = QtGui.QLabel(self.frame)
|
||||
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.MinimumExpanding, QtGui.QSizePolicy.Preferred)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.prop_url.sizePolicy().hasHeightForWidth())
|
||||
self.prop_url.setSizePolicy(sizePolicy)
|
||||
self.prop_url.setMinimumSize(QtCore.QSize(300, 0))
|
||||
self.prop_url.setFrameShape(QtGui.QFrame.StyledPanel)
|
||||
self.prop_url.setFrameShadow(QtGui.QFrame.Sunken)
|
||||
self.prop_url.setText(_fromUtf8(""))
|
||||
self.prop_url.setTextFormat(QtCore.Qt.RichText)
|
||||
self.prop_url.setOpenExternalLinks(True)
|
||||
self.prop_url.setTextInteractionFlags(QtCore.Qt.LinksAccessibleByMouse|QtCore.Qt.TextSelectableByMouse)
|
||||
self.prop_url.setObjectName(_fromUtf8("prop_url"))
|
||||
self.formLayout.setWidget(0, QtGui.QFormLayout.FieldRole, self.prop_url)
|
||||
self.label_3 = QtGui.QLabel(self.frame)
|
||||
self.label_3.setObjectName(_fromUtf8("label_3"))
|
||||
self.formLayout.setWidget(1, QtGui.QFormLayout.LabelRole, self.label_3)
|
||||
self.prop_name = QtGui.QLabel(self.frame)
|
||||
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.MinimumExpanding, QtGui.QSizePolicy.Preferred)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.prop_name.sizePolicy().hasHeightForWidth())
|
||||
self.prop_name.setSizePolicy(sizePolicy)
|
||||
self.prop_name.setMinimumSize(QtCore.QSize(300, 0))
|
||||
self.prop_name.setFrameShape(QtGui.QFrame.StyledPanel)
|
||||
self.prop_name.setFrameShadow(QtGui.QFrame.Sunken)
|
||||
self.prop_name.setText(_fromUtf8(""))
|
||||
self.prop_name.setTextFormat(QtCore.Qt.PlainText)
|
||||
self.prop_name.setTextInteractionFlags(QtCore.Qt.LinksAccessibleByMouse|QtCore.Qt.TextSelectableByMouse)
|
||||
self.prop_name.setObjectName(_fromUtf8("prop_name"))
|
||||
self.formLayout.setWidget(1, QtGui.QFormLayout.FieldRole, self.prop_name)
|
||||
self.label_4 = QtGui.QLabel(self.frame)
|
||||
self.label_4.setObjectName(_fromUtf8("label_4"))
|
||||
self.formLayout.setWidget(2, QtGui.QFormLayout.LabelRole, self.label_4)
|
||||
self.prop_parenturl = QtGui.QLabel(self.frame)
|
||||
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.MinimumExpanding, QtGui.QSizePolicy.Preferred)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.prop_parenturl.sizePolicy().hasHeightForWidth())
|
||||
self.prop_parenturl.setSizePolicy(sizePolicy)
|
||||
self.prop_parenturl.setMinimumSize(QtCore.QSize(300, 0))
|
||||
self.prop_parenturl.setFrameShape(QtGui.QFrame.StyledPanel)
|
||||
self.prop_parenturl.setFrameShadow(QtGui.QFrame.Sunken)
|
||||
self.prop_parenturl.setText(_fromUtf8(""))
|
||||
self.prop_parenturl.setTextFormat(QtCore.Qt.RichText)
|
||||
self.prop_parenturl.setOpenExternalLinks(True)
|
||||
self.prop_parenturl.setTextInteractionFlags(QtCore.Qt.LinksAccessibleByMouse|QtCore.Qt.TextSelectableByMouse)
|
||||
self.prop_parenturl.setObjectName(_fromUtf8("prop_parenturl"))
|
||||
self.formLayout.setWidget(2, QtGui.QFormLayout.FieldRole, self.prop_parenturl)
|
||||
self.label_5 = QtGui.QLabel(self.frame)
|
||||
self.label_5.setObjectName(_fromUtf8("label_5"))
|
||||
self.formLayout.setWidget(3, QtGui.QFormLayout.LabelRole, self.label_5)
|
||||
self.prop_base = QtGui.QLabel(self.frame)
|
||||
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.MinimumExpanding, QtGui.QSizePolicy.Preferred)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.prop_base.sizePolicy().hasHeightForWidth())
|
||||
self.prop_base.setSizePolicy(sizePolicy)
|
||||
self.prop_base.setMinimumSize(QtCore.QSize(300, 0))
|
||||
self.prop_base.setFrameShape(QtGui.QFrame.StyledPanel)
|
||||
self.prop_base.setFrameShadow(QtGui.QFrame.Sunken)
|
||||
self.prop_base.setText(_fromUtf8(""))
|
||||
self.prop_base.setTextFormat(QtCore.Qt.RichText)
|
||||
self.prop_base.setOpenExternalLinks(False)
|
||||
self.prop_base.setTextInteractionFlags(QtCore.Qt.LinksAccessibleByMouse|QtCore.Qt.TextSelectableByMouse)
|
||||
self.prop_base.setObjectName(_fromUtf8("prop_base"))
|
||||
self.formLayout.setWidget(3, QtGui.QFormLayout.FieldRole, self.prop_base)
|
||||
self.label_7 = QtGui.QLabel(self.frame)
|
||||
self.label_7.setObjectName(_fromUtf8("label_7"))
|
||||
self.formLayout.setWidget(4, QtGui.QFormLayout.LabelRole, self.label_7)
|
||||
self.prop_checktime = QtGui.QLabel(self.frame)
|
||||
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.MinimumExpanding, QtGui.QSizePolicy.Preferred)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.prop_checktime.sizePolicy().hasHeightForWidth())
|
||||
self.prop_checktime.setSizePolicy(sizePolicy)
|
||||
self.prop_checktime.setMinimumSize(QtCore.QSize(300, 0))
|
||||
self.prop_checktime.setFrameShape(QtGui.QFrame.StyledPanel)
|
||||
self.prop_checktime.setFrameShadow(QtGui.QFrame.Sunken)
|
||||
self.prop_checktime.setText(_fromUtf8(""))
|
||||
self.prop_checktime.setTextFormat(QtCore.Qt.PlainText)
|
||||
self.prop_checktime.setTextInteractionFlags(QtCore.Qt.LinksAccessibleByMouse|QtCore.Qt.TextSelectableByMouse)
|
||||
self.prop_checktime.setObjectName(_fromUtf8("prop_checktime"))
|
||||
self.formLayout.setWidget(4, QtGui.QFormLayout.FieldRole, self.prop_checktime)
|
||||
self.label_8 = QtGui.QLabel(self.frame)
|
||||
self.label_8.setObjectName(_fromUtf8("label_8"))
|
||||
self.formLayout.setWidget(5, QtGui.QFormLayout.LabelRole, self.label_8)
|
||||
self.prop_dltime = QtGui.QLabel(self.frame)
|
||||
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.MinimumExpanding, QtGui.QSizePolicy.Preferred)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.prop_dltime.sizePolicy().hasHeightForWidth())
|
||||
self.prop_dltime.setSizePolicy(sizePolicy)
|
||||
self.prop_dltime.setMinimumSize(QtCore.QSize(300, 0))
|
||||
self.prop_dltime.setFrameShape(QtGui.QFrame.StyledPanel)
|
||||
self.prop_dltime.setFrameShadow(QtGui.QFrame.Sunken)
|
||||
self.prop_dltime.setText(_fromUtf8(""))
|
||||
self.prop_dltime.setTextFormat(QtCore.Qt.PlainText)
|
||||
self.prop_dltime.setTextInteractionFlags(QtCore.Qt.LinksAccessibleByMouse|QtCore.Qt.TextSelectableByMouse)
|
||||
self.prop_dltime.setObjectName(_fromUtf8("prop_dltime"))
|
||||
self.formLayout.setWidget(5, QtGui.QFormLayout.FieldRole, self.prop_dltime)
|
||||
self.label_9 = QtGui.QLabel(self.frame)
|
||||
self.label_9.setObjectName(_fromUtf8("label_9"))
|
||||
self.formLayout.setWidget(6, QtGui.QFormLayout.LabelRole, self.label_9)
|
||||
self.prop_size = QtGui.QLabel(self.frame)
|
||||
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.MinimumExpanding, QtGui.QSizePolicy.Preferred)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.prop_size.sizePolicy().hasHeightForWidth())
|
||||
self.prop_size.setSizePolicy(sizePolicy)
|
||||
self.prop_size.setMinimumSize(QtCore.QSize(300, 0))
|
||||
self.prop_size.setFrameShape(QtGui.QFrame.StyledPanel)
|
||||
self.prop_size.setFrameShadow(QtGui.QFrame.Sunken)
|
||||
self.prop_size.setText(_fromUtf8(""))
|
||||
self.prop_size.setTextFormat(QtCore.Qt.PlainText)
|
||||
self.prop_size.setTextInteractionFlags(QtCore.Qt.LinksAccessibleByMouse|QtCore.Qt.TextSelectableByMouse)
|
||||
self.prop_size.setObjectName(_fromUtf8("prop_size"))
|
||||
self.formLayout.setWidget(6, QtGui.QFormLayout.FieldRole, self.prop_size)
|
||||
self.label_10 = QtGui.QLabel(self.frame)
|
||||
self.label_10.setObjectName(_fromUtf8("label_10"))
|
||||
self.formLayout.setWidget(8, QtGui.QFormLayout.LabelRole, self.label_10)
|
||||
self.prop_info = QtGui.QLabel(self.frame)
|
||||
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.MinimumExpanding, QtGui.QSizePolicy.Preferred)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.prop_info.sizePolicy().hasHeightForWidth())
|
||||
self.prop_info.setSizePolicy(sizePolicy)
|
||||
self.prop_info.setMinimumSize(QtCore.QSize(300, 0))
|
||||
self.prop_info.setFrameShape(QtGui.QFrame.StyledPanel)
|
||||
self.prop_info.setFrameShadow(QtGui.QFrame.Sunken)
|
||||
self.prop_info.setText(_fromUtf8(""))
|
||||
self.prop_info.setTextFormat(QtCore.Qt.PlainText)
|
||||
self.prop_info.setWordWrap(True)
|
||||
self.prop_info.setTextInteractionFlags(QtCore.Qt.LinksAccessibleByMouse|QtCore.Qt.TextSelectableByMouse)
|
||||
self.prop_info.setObjectName(_fromUtf8("prop_info"))
|
||||
self.formLayout.setWidget(8, QtGui.QFormLayout.FieldRole, self.prop_info)
|
||||
self.label_11 = QtGui.QLabel(self.frame)
|
||||
self.label_11.setObjectName(_fromUtf8("label_11"))
|
||||
self.formLayout.setWidget(9, QtGui.QFormLayout.LabelRole, self.label_11)
|
||||
self.prop_warning = QtGui.QLabel(self.frame)
|
||||
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.MinimumExpanding, QtGui.QSizePolicy.Preferred)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.prop_warning.sizePolicy().hasHeightForWidth())
|
||||
self.prop_warning.setSizePolicy(sizePolicy)
|
||||
self.prop_warning.setMinimumSize(QtCore.QSize(300, 0))
|
||||
self.prop_warning.setFrameShape(QtGui.QFrame.StyledPanel)
|
||||
self.prop_warning.setFrameShadow(QtGui.QFrame.Sunken)
|
||||
self.prop_warning.setText(_fromUtf8(""))
|
||||
self.prop_warning.setTextFormat(QtCore.Qt.PlainText)
|
||||
self.prop_warning.setScaledContents(True)
|
||||
self.prop_warning.setWordWrap(True)
|
||||
self.prop_warning.setTextInteractionFlags(QtCore.Qt.LinksAccessibleByMouse|QtCore.Qt.TextSelectableByMouse)
|
||||
self.prop_warning.setObjectName(_fromUtf8("prop_warning"))
|
||||
self.formLayout.setWidget(9, QtGui.QFormLayout.FieldRole, self.prop_warning)
|
||||
self.label_12 = QtGui.QLabel(self.frame)
|
||||
self.label_12.setObjectName(_fromUtf8("label_12"))
|
||||
self.formLayout.setWidget(10, QtGui.QFormLayout.LabelRole, self.label_12)
|
||||
self.prop_result = QtGui.QLabel(self.frame)
|
||||
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.MinimumExpanding, QtGui.QSizePolicy.Preferred)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.prop_result.sizePolicy().hasHeightForWidth())
|
||||
self.prop_result.setSizePolicy(sizePolicy)
|
||||
self.prop_result.setMinimumSize(QtCore.QSize(300, 0))
|
||||
self.prop_result.setFrameShape(QtGui.QFrame.StyledPanel)
|
||||
self.prop_result.setFrameShadow(QtGui.QFrame.Sunken)
|
||||
self.prop_result.setText(_fromUtf8(""))
|
||||
self.prop_result.setTextFormat(QtCore.Qt.PlainText)
|
||||
self.prop_result.setTextInteractionFlags(QtCore.Qt.LinksAccessibleByMouse|QtCore.Qt.TextSelectableByMouse)
|
||||
self.prop_result.setObjectName(_fromUtf8("prop_result"))
|
||||
self.formLayout.setWidget(10, QtGui.QFormLayout.FieldRole, self.prop_result)
|
||||
self.label_16 = QtGui.QLabel(self.frame)
|
||||
self.label_16.setObjectName(_fromUtf8("label_16"))
|
||||
self.formLayout.setWidget(7, QtGui.QFormLayout.LabelRole, self.label_16)
|
||||
self.prop_modified = QtGui.QLabel(self.frame)
|
||||
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.MinimumExpanding, QtGui.QSizePolicy.Preferred)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.prop_modified.sizePolicy().hasHeightForWidth())
|
||||
self.prop_modified.setSizePolicy(sizePolicy)
|
||||
self.prop_modified.setMinimumSize(QtCore.QSize(300, 0))
|
||||
self.prop_modified.setFrameShape(QtGui.QFrame.StyledPanel)
|
||||
self.prop_modified.setFrameShadow(QtGui.QFrame.Sunken)
|
||||
self.prop_modified.setText(_fromUtf8(""))
|
||||
self.prop_modified.setTextFormat(QtCore.Qt.PlainText)
|
||||
self.prop_modified.setTextInteractionFlags(QtCore.Qt.LinksAccessibleByMouse|QtCore.Qt.TextSelectableByMouse)
|
||||
self.prop_modified.setObjectName(_fromUtf8("prop_modified"))
|
||||
self.formLayout.setWidget(7, QtGui.QFormLayout.FieldRole, self.prop_modified)
|
||||
self.horizontalLayout_2.addWidget(self.frame)
|
||||
self.horizontalLayout.addWidget(self.url_properties)
|
||||
self.statistics = QtGui.QFrame(self.centralwidget)
|
||||
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Preferred)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.statistics.sizePolicy().hasHeightForWidth())
|
||||
self.statistics.setSizePolicy(sizePolicy)
|
||||
self.statistics.setLineWidth(0)
|
||||
self.statistics.setObjectName(_fromUtf8("statistics"))
|
||||
self.verticalLayout_2 = QtGui.QVBoxLayout(self.statistics)
|
||||
self.verticalLayout_2.setObjectName(_fromUtf8("verticalLayout_2"))
|
||||
self.groupBox = QtGui.QGroupBox(self.statistics)
|
||||
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Preferred)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.groupBox.sizePolicy().hasHeightForWidth())
|
||||
self.groupBox.setSizePolicy(sizePolicy)
|
||||
font = QtGui.QFont()
|
||||
font.setBold(True)
|
||||
font.setWeight(75)
|
||||
self.groupBox.setFont(font)
|
||||
self.groupBox.setObjectName(_fromUtf8("groupBox"))
|
||||
self.gridLayout = QtGui.QGridLayout(self.groupBox)
|
||||
self.gridLayout.setObjectName(_fromUtf8("gridLayout"))
|
||||
self.label_24 = QtGui.QLabel(self.groupBox)
|
||||
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Preferred)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.label_24.sizePolicy().hasHeightForWidth())
|
||||
self.label_24.setSizePolicy(sizePolicy)
|
||||
self.label_24.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
|
||||
self.label_24.setObjectName(_fromUtf8("label_24"))
|
||||
self.gridLayout.addWidget(self.label_24, 0, 0, 1, 1)
|
||||
self.stats_valid_urls = QtGui.QLabel(self.groupBox)
|
||||
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Preferred)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.stats_valid_urls.sizePolicy().hasHeightForWidth())
|
||||
self.stats_valid_urls.setSizePolicy(sizePolicy)
|
||||
self.stats_valid_urls.setMinimumSize(QtCore.QSize(30, 0))
|
||||
self.stats_valid_urls.setFrameShape(QtGui.QFrame.StyledPanel)
|
||||
self.stats_valid_urls.setFrameShadow(QtGui.QFrame.Sunken)
|
||||
self.stats_valid_urls.setText(_fromUtf8(""))
|
||||
self.stats_valid_urls.setTextFormat(QtCore.Qt.RichText)
|
||||
self.stats_valid_urls.setOpenExternalLinks(True)
|
||||
self.stats_valid_urls.setObjectName(_fromUtf8("stats_valid_urls"))
|
||||
self.gridLayout.addWidget(self.stats_valid_urls, 0, 1, 1, 1)
|
||||
self.label_26 = QtGui.QLabel(self.groupBox)
|
||||
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Preferred)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.label_26.sizePolicy().hasHeightForWidth())
|
||||
self.label_26.setSizePolicy(sizePolicy)
|
||||
self.label_26.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
|
||||
self.label_26.setObjectName(_fromUtf8("label_26"))
|
||||
self.gridLayout.addWidget(self.label_26, 0, 2, 1, 1)
|
||||
self.stats_warnings = QtGui.QLabel(self.groupBox)
|
||||
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Preferred)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.stats_warnings.sizePolicy().hasHeightForWidth())
|
||||
self.stats_warnings.setSizePolicy(sizePolicy)
|
||||
self.stats_warnings.setMinimumSize(QtCore.QSize(30, 0))
|
||||
self.stats_warnings.setFrameShape(QtGui.QFrame.StyledPanel)
|
||||
self.stats_warnings.setFrameShadow(QtGui.QFrame.Sunken)
|
||||
self.stats_warnings.setText(_fromUtf8(""))
|
||||
self.stats_warnings.setTextFormat(QtCore.Qt.RichText)
|
||||
self.stats_warnings.setOpenExternalLinks(True)
|
||||
self.stats_warnings.setObjectName(_fromUtf8("stats_warnings"))
|
||||
self.gridLayout.addWidget(self.stats_warnings, 0, 3, 1, 1)
|
||||
self.label_25 = QtGui.QLabel(self.groupBox)
|
||||
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Preferred)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.label_25.sizePolicy().hasHeightForWidth())
|
||||
self.label_25.setSizePolicy(sizePolicy)
|
||||
self.label_25.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
|
||||
self.label_25.setObjectName(_fromUtf8("label_25"))
|
||||
self.gridLayout.addWidget(self.label_25, 1, 0, 1, 1)
|
||||
self.stats_invalid_urls = QtGui.QLabel(self.groupBox)
|
||||
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Preferred)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.stats_invalid_urls.sizePolicy().hasHeightForWidth())
|
||||
self.stats_invalid_urls.setSizePolicy(sizePolicy)
|
||||
self.stats_invalid_urls.setMinimumSize(QtCore.QSize(30, 0))
|
||||
self.stats_invalid_urls.setFrameShape(QtGui.QFrame.StyledPanel)
|
||||
self.stats_invalid_urls.setFrameShadow(QtGui.QFrame.Sunken)
|
||||
self.stats_invalid_urls.setText(_fromUtf8(""))
|
||||
self.stats_invalid_urls.setTextFormat(QtCore.Qt.RichText)
|
||||
self.stats_invalid_urls.setOpenExternalLinks(True)
|
||||
self.stats_invalid_urls.setObjectName(_fromUtf8("stats_invalid_urls"))
|
||||
self.gridLayout.addWidget(self.stats_invalid_urls, 1, 1, 1, 1)
|
||||
self.verticalLayout_2.addWidget(self.groupBox)
|
||||
self.groupBox_3 = QtGui.QGroupBox(self.statistics)
|
||||
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Preferred)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.groupBox_3.sizePolicy().hasHeightForWidth())
|
||||
self.groupBox_3.setSizePolicy(sizePolicy)
|
||||
self.groupBox_3.setObjectName(_fromUtf8("groupBox_3"))
|
||||
self.gridLayout_2 = QtGui.QGridLayout(self.groupBox_3)
|
||||
self.gridLayout_2.setObjectName(_fromUtf8("gridLayout_2"))
|
||||
self.label_6 = QtGui.QLabel(self.groupBox_3)
|
||||
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Preferred)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.label_6.sizePolicy().hasHeightForWidth())
|
||||
self.label_6.setSizePolicy(sizePolicy)
|
||||
self.label_6.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
|
||||
self.label_6.setObjectName(_fromUtf8("label_6"))
|
||||
self.gridLayout_2.addWidget(self.label_6, 0, 0, 1, 1)
|
||||
self.stats_content_image = QtGui.QLabel(self.groupBox_3)
|
||||
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Preferred)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.stats_content_image.sizePolicy().hasHeightForWidth())
|
||||
self.stats_content_image.setSizePolicy(sizePolicy)
|
||||
self.stats_content_image.setMinimumSize(QtCore.QSize(40, 0))
|
||||
self.stats_content_image.setFrameShape(QtGui.QFrame.StyledPanel)
|
||||
self.stats_content_image.setFrameShadow(QtGui.QFrame.Sunken)
|
||||
self.stats_content_image.setText(_fromUtf8(""))
|
||||
self.stats_content_image.setTextFormat(QtCore.Qt.RichText)
|
||||
self.stats_content_image.setOpenExternalLinks(True)
|
||||
self.stats_content_image.setObjectName(_fromUtf8("stats_content_image"))
|
||||
self.gridLayout_2.addWidget(self.stats_content_image, 0, 1, 1, 1)
|
||||
self.label_13 = QtGui.QLabel(self.groupBox_3)
|
||||
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Preferred)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.label_13.sizePolicy().hasHeightForWidth())
|
||||
self.label_13.setSizePolicy(sizePolicy)
|
||||
self.label_13.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
|
||||
self.label_13.setObjectName(_fromUtf8("label_13"))
|
||||
self.gridLayout_2.addWidget(self.label_13, 0, 2, 1, 1)
|
||||
self.stats_content_text = QtGui.QLabel(self.groupBox_3)
|
||||
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Preferred)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.stats_content_text.sizePolicy().hasHeightForWidth())
|
||||
self.stats_content_text.setSizePolicy(sizePolicy)
|
||||
self.stats_content_text.setMinimumSize(QtCore.QSize(40, 0))
|
||||
self.stats_content_text.setFrameShape(QtGui.QFrame.StyledPanel)
|
||||
self.stats_content_text.setFrameShadow(QtGui.QFrame.Sunken)
|
||||
self.stats_content_text.setText(_fromUtf8(""))
|
||||
self.stats_content_text.setTextFormat(QtCore.Qt.RichText)
|
||||
self.stats_content_text.setOpenExternalLinks(True)
|
||||
self.stats_content_text.setObjectName(_fromUtf8("stats_content_text"))
|
||||
self.gridLayout_2.addWidget(self.stats_content_text, 0, 3, 1, 1)
|
||||
self.label_27 = QtGui.QLabel(self.groupBox_3)
|
||||
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Preferred)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.label_27.sizePolicy().hasHeightForWidth())
|
||||
self.label_27.setSizePolicy(sizePolicy)
|
||||
self.label_27.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
|
||||
self.label_27.setObjectName(_fromUtf8("label_27"))
|
||||
self.gridLayout_2.addWidget(self.label_27, 0, 4, 1, 1)
|
||||
self.stats_content_application = QtGui.QLabel(self.groupBox_3)
|
||||
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Preferred)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.stats_content_application.sizePolicy().hasHeightForWidth())
|
||||
self.stats_content_application.setSizePolicy(sizePolicy)
|
||||
self.stats_content_application.setMinimumSize(QtCore.QSize(40, 0))
|
||||
self.stats_content_application.setFrameShape(QtGui.QFrame.StyledPanel)
|
||||
self.stats_content_application.setFrameShadow(QtGui.QFrame.Sunken)
|
||||
self.stats_content_application.setText(_fromUtf8(""))
|
||||
self.stats_content_application.setTextFormat(QtCore.Qt.RichText)
|
||||
self.stats_content_application.setOpenExternalLinks(True)
|
||||
self.stats_content_application.setObjectName(_fromUtf8("stats_content_application"))
|
||||
self.gridLayout_2.addWidget(self.stats_content_application, 0, 5, 1, 1)
|
||||
self.label_17 = QtGui.QLabel(self.groupBox_3)
|
||||
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Preferred)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.label_17.sizePolicy().hasHeightForWidth())
|
||||
self.label_17.setSizePolicy(sizePolicy)
|
||||
self.label_17.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
|
||||
self.label_17.setObjectName(_fromUtf8("label_17"))
|
||||
self.gridLayout_2.addWidget(self.label_17, 1, 0, 1, 1)
|
||||
self.stats_content_audio = QtGui.QLabel(self.groupBox_3)
|
||||
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Preferred)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.stats_content_audio.sizePolicy().hasHeightForWidth())
|
||||
self.stats_content_audio.setSizePolicy(sizePolicy)
|
||||
self.stats_content_audio.setMinimumSize(QtCore.QSize(40, 0))
|
||||
self.stats_content_audio.setFrameShape(QtGui.QFrame.StyledPanel)
|
||||
self.stats_content_audio.setFrameShadow(QtGui.QFrame.Sunken)
|
||||
self.stats_content_audio.setText(_fromUtf8(""))
|
||||
self.stats_content_audio.setTextFormat(QtCore.Qt.RichText)
|
||||
self.stats_content_audio.setOpenExternalLinks(True)
|
||||
self.stats_content_audio.setObjectName(_fromUtf8("stats_content_audio"))
|
||||
self.gridLayout_2.addWidget(self.stats_content_audio, 1, 1, 1, 1)
|
||||
self.label_21 = QtGui.QLabel(self.groupBox_3)
|
||||
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Preferred)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.label_21.sizePolicy().hasHeightForWidth())
|
||||
self.label_21.setSizePolicy(sizePolicy)
|
||||
self.label_21.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
|
||||
self.label_21.setObjectName(_fromUtf8("label_21"))
|
||||
self.gridLayout_2.addWidget(self.label_21, 1, 2, 1, 1)
|
||||
self.stats_content_video = QtGui.QLabel(self.groupBox_3)
|
||||
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Preferred)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.stats_content_video.sizePolicy().hasHeightForWidth())
|
||||
self.stats_content_video.setSizePolicy(sizePolicy)
|
||||
self.stats_content_video.setMinimumSize(QtCore.QSize(40, 0))
|
||||
self.stats_content_video.setFrameShape(QtGui.QFrame.StyledPanel)
|
||||
self.stats_content_video.setFrameShadow(QtGui.QFrame.Sunken)
|
||||
self.stats_content_video.setText(_fromUtf8(""))
|
||||
self.stats_content_video.setTextFormat(QtCore.Qt.RichText)
|
||||
self.stats_content_video.setOpenExternalLinks(True)
|
||||
self.stats_content_video.setObjectName(_fromUtf8("stats_content_video"))
|
||||
self.gridLayout_2.addWidget(self.stats_content_video, 1, 3, 1, 1)
|
||||
self.stats_content_other = QtGui.QLabel(self.groupBox_3)
|
||||
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Preferred)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.stats_content_other.sizePolicy().hasHeightForWidth())
|
||||
self.stats_content_other.setSizePolicy(sizePolicy)
|
||||
self.stats_content_other.setMinimumSize(QtCore.QSize(40, 0))
|
||||
self.stats_content_other.setFrameShape(QtGui.QFrame.StyledPanel)
|
||||
self.stats_content_other.setFrameShadow(QtGui.QFrame.Sunken)
|
||||
self.stats_content_other.setText(_fromUtf8(""))
|
||||
self.stats_content_other.setTextFormat(QtCore.Qt.RichText)
|
||||
self.stats_content_other.setOpenExternalLinks(True)
|
||||
self.stats_content_other.setObjectName(_fromUtf8("stats_content_other"))
|
||||
self.gridLayout_2.addWidget(self.stats_content_other, 2, 5, 1, 1)
|
||||
self.label_23 = QtGui.QLabel(self.groupBox_3)
|
||||
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Preferred)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.label_23.sizePolicy().hasHeightForWidth())
|
||||
self.label_23.setSizePolicy(sizePolicy)
|
||||
self.label_23.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
|
||||
self.label_23.setObjectName(_fromUtf8("label_23"))
|
||||
self.gridLayout_2.addWidget(self.label_23, 2, 4, 1, 1)
|
||||
self.stats_content_mail = QtGui.QLabel(self.groupBox_3)
|
||||
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Preferred)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.stats_content_mail.sizePolicy().hasHeightForWidth())
|
||||
self.stats_content_mail.setSizePolicy(sizePolicy)
|
||||
self.stats_content_mail.setMinimumSize(QtCore.QSize(40, 0))
|
||||
self.stats_content_mail.setFrameShape(QtGui.QFrame.StyledPanel)
|
||||
self.stats_content_mail.setFrameShadow(QtGui.QFrame.Sunken)
|
||||
self.stats_content_mail.setText(_fromUtf8(""))
|
||||
self.stats_content_mail.setTextFormat(QtCore.Qt.RichText)
|
||||
self.stats_content_mail.setOpenExternalLinks(True)
|
||||
self.stats_content_mail.setObjectName(_fromUtf8("stats_content_mail"))
|
||||
self.gridLayout_2.addWidget(self.stats_content_mail, 1, 5, 1, 1)
|
||||
self.label_22 = QtGui.QLabel(self.groupBox_3)
|
||||
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Preferred)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.label_22.sizePolicy().hasHeightForWidth())
|
||||
self.label_22.setSizePolicy(sizePolicy)
|
||||
self.label_22.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
|
||||
self.label_22.setObjectName(_fromUtf8("label_22"))
|
||||
self.gridLayout_2.addWidget(self.label_22, 1, 4, 1, 1)
|
||||
self.verticalLayout_2.addWidget(self.groupBox_3)
|
||||
self.groupBox_2 = QtGui.QGroupBox(self.statistics)
|
||||
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Preferred)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.groupBox_2.sizePolicy().hasHeightForWidth())
|
||||
self.groupBox_2.setSizePolicy(sizePolicy)
|
||||
self.groupBox_2.setObjectName(_fromUtf8("groupBox_2"))
|
||||
self.gridLayout_3 = QtGui.QGridLayout(self.groupBox_2)
|
||||
self.gridLayout_3.setObjectName(_fromUtf8("gridLayout_3"))
|
||||
self.label_18 = QtGui.QLabel(self.groupBox_2)
|
||||
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Preferred)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.label_18.sizePolicy().hasHeightForWidth())
|
||||
self.label_18.setSizePolicy(sizePolicy)
|
||||
self.label_18.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
|
||||
self.label_18.setObjectName(_fromUtf8("label_18"))
|
||||
self.gridLayout_3.addWidget(self.label_18, 0, 0, 1, 1)
|
||||
self.stats_url_minlen = QtGui.QLabel(self.groupBox_2)
|
||||
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Preferred)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.stats_url_minlen.sizePolicy().hasHeightForWidth())
|
||||
self.stats_url_minlen.setSizePolicy(sizePolicy)
|
||||
self.stats_url_minlen.setMinimumSize(QtCore.QSize(30, 0))
|
||||
self.stats_url_minlen.setFrameShape(QtGui.QFrame.StyledPanel)
|
||||
self.stats_url_minlen.setFrameShadow(QtGui.QFrame.Sunken)
|
||||
self.stats_url_minlen.setText(_fromUtf8(""))
|
||||
self.stats_url_minlen.setTextFormat(QtCore.Qt.RichText)
|
||||
self.stats_url_minlen.setOpenExternalLinks(True)
|
||||
self.stats_url_minlen.setObjectName(_fromUtf8("stats_url_minlen"))
|
||||
self.gridLayout_3.addWidget(self.stats_url_minlen, 0, 1, 1, 1)
|
||||
self.label_20 = QtGui.QLabel(self.groupBox_2)
|
||||
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Preferred)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.label_20.sizePolicy().hasHeightForWidth())
|
||||
self.label_20.setSizePolicy(sizePolicy)
|
||||
self.label_20.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
|
||||
self.label_20.setObjectName(_fromUtf8("label_20"))
|
||||
self.gridLayout_3.addWidget(self.label_20, 0, 2, 1, 1)
|
||||
self.stats_url_avglen = QtGui.QLabel(self.groupBox_2)
|
||||
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Preferred)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.stats_url_avglen.sizePolicy().hasHeightForWidth())
|
||||
self.stats_url_avglen.setSizePolicy(sizePolicy)
|
||||
self.stats_url_avglen.setMinimumSize(QtCore.QSize(30, 0))
|
||||
self.stats_url_avglen.setFrameShape(QtGui.QFrame.StyledPanel)
|
||||
self.stats_url_avglen.setFrameShadow(QtGui.QFrame.Sunken)
|
||||
self.stats_url_avglen.setText(_fromUtf8(""))
|
||||
self.stats_url_avglen.setTextFormat(QtCore.Qt.RichText)
|
||||
self.stats_url_avglen.setOpenExternalLinks(True)
|
||||
self.stats_url_avglen.setObjectName(_fromUtf8("stats_url_avglen"))
|
||||
self.gridLayout_3.addWidget(self.stats_url_avglen, 0, 3, 1, 1)
|
||||
self.label_19 = QtGui.QLabel(self.groupBox_2)
|
||||
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Preferred)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.label_19.sizePolicy().hasHeightForWidth())
|
||||
self.label_19.setSizePolicy(sizePolicy)
|
||||
self.label_19.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
|
||||
self.label_19.setObjectName(_fromUtf8("label_19"))
|
||||
self.gridLayout_3.addWidget(self.label_19, 1, 0, 1, 1)
|
||||
self.stats_url_maxlen = QtGui.QLabel(self.groupBox_2)
|
||||
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Preferred)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.stats_url_maxlen.sizePolicy().hasHeightForWidth())
|
||||
self.stats_url_maxlen.setSizePolicy(sizePolicy)
|
||||
self.stats_url_maxlen.setMinimumSize(QtCore.QSize(30, 0))
|
||||
self.stats_url_maxlen.setFrameShape(QtGui.QFrame.StyledPanel)
|
||||
self.stats_url_maxlen.setFrameShadow(QtGui.QFrame.Sunken)
|
||||
self.stats_url_maxlen.setText(_fromUtf8(""))
|
||||
self.stats_url_maxlen.setTextFormat(QtCore.Qt.RichText)
|
||||
self.stats_url_maxlen.setOpenExternalLinks(True)
|
||||
self.stats_url_maxlen.setObjectName(_fromUtf8("stats_url_maxlen"))
|
||||
self.gridLayout_3.addWidget(self.stats_url_maxlen, 1, 1, 1, 1)
|
||||
self.verticalLayout_2.addWidget(self.groupBox_2)
|
||||
self.horizontalLayout.addWidget(self.statistics)
|
||||
self.verticalLayout.addLayout(self.horizontalLayout)
|
||||
MainWindow.setCentralWidget(self.centralwidget)
|
||||
self.menubar = QtGui.QMenuBar(MainWindow)
|
||||
self.menubar.setGeometry(QtCore.QRect(0, 0, 713, 20))
|
||||
self.menubar.setObjectName(_fromUtf8("menubar"))
|
||||
self.menuEdit = QtGui.QMenu(self.menubar)
|
||||
self.menuEdit.setObjectName(_fromUtf8("menuEdit"))
|
||||
self.menuFile = QtGui.QMenu(self.menubar)
|
||||
self.menuFile.setObjectName(_fromUtf8("menuFile"))
|
||||
self.menuHelp = QtGui.QMenu(self.menubar)
|
||||
self.menuHelp.setObjectName(_fromUtf8("menuHelp"))
|
||||
MainWindow.setMenuBar(self.menubar)
|
||||
self.statusBar = QtGui.QStatusBar(MainWindow)
|
||||
self.statusBar.setObjectName(_fromUtf8("statusBar"))
|
||||
MainWindow.setStatusBar(self.statusBar)
|
||||
self.actionAbout = QtGui.QAction(MainWindow)
|
||||
icon2 = QtGui.QIcon()
|
||||
icon2.addPixmap(QtGui.QPixmap(_fromUtf8(":/icons/about.png")), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
self.actionAbout.setIcon(icon2)
|
||||
self.actionAbout.setObjectName(_fromUtf8("actionAbout"))
|
||||
self.actionHelp = QtGui.QAction(MainWindow)
|
||||
icon3 = QtGui.QIcon()
|
||||
icon3.addPixmap(QtGui.QPixmap(_fromUtf8(":/icons/help.png")), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
self.actionHelp.setIcon(icon3)
|
||||
self.actionHelp.setObjectName(_fromUtf8("actionHelp"))
|
||||
self.actionViewOnline = QtGui.QAction(MainWindow)
|
||||
icon4 = QtGui.QIcon()
|
||||
icon4.addPixmap(QtGui.QPixmap(_fromUtf8(":/icons/online.png")), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
self.actionViewOnline.setIcon(icon4)
|
||||
self.actionViewOnline.setObjectName(_fromUtf8("actionViewOnline"))
|
||||
self.actionOptions = QtGui.QAction(MainWindow)
|
||||
icon5 = QtGui.QIcon()
|
||||
icon5.addPixmap(QtGui.QPixmap(_fromUtf8(":/icons/preferences.png")), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
self.actionOptions.setIcon(icon5)
|
||||
self.actionOptions.setObjectName(_fromUtf8("actionOptions"))
|
||||
self.actionCopyToClipboard = QtGui.QAction(MainWindow)
|
||||
icon6 = QtGui.QIcon()
|
||||
icon6.addPixmap(QtGui.QPixmap(_fromUtf8(":/icons/copy.png")), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
self.actionCopyToClipboard.setIcon(icon6)
|
||||
self.actionCopyToClipboard.setObjectName(_fromUtf8("actionCopyToClipboard"))
|
||||
self.actionViewParentOnline = QtGui.QAction(MainWindow)
|
||||
self.actionViewParentOnline.setIcon(icon4)
|
||||
self.actionViewParentOnline.setObjectName(_fromUtf8("actionViewParentOnline"))
|
||||
self.actionViewParentSource = QtGui.QAction(MainWindow)
|
||||
self.actionViewParentSource.setIcon(icon4)
|
||||
self.actionViewParentSource.setObjectName(_fromUtf8("actionViewParentSource"))
|
||||
self.actionDebug = QtGui.QAction(MainWindow)
|
||||
self.actionDebug.setObjectName(_fromUtf8("actionDebug"))
|
||||
self.actionViewProperties = QtGui.QAction(MainWindow)
|
||||
self.actionViewProperties.setObjectName(_fromUtf8("actionViewProperties"))
|
||||
self.actionSave = QtGui.QAction(MainWindow)
|
||||
icon7 = QtGui.QIcon()
|
||||
icon7.addPixmap(QtGui.QPixmap(_fromUtf8(":/icons/save.png")), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
self.actionSave.setIcon(icon7)
|
||||
self.actionSave.setObjectName(_fromUtf8("actionSave"))
|
||||
self.actionQuit = QtGui.QAction(MainWindow)
|
||||
icon8 = QtGui.QIcon()
|
||||
icon8.addPixmap(QtGui.QPixmap(_fromUtf8(":/icons/exit.png")), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
self.actionQuit.setIcon(icon8)
|
||||
self.actionQuit.setObjectName(_fromUtf8("actionQuit"))
|
||||
self.actionCheckUpdates = QtGui.QAction(MainWindow)
|
||||
self.actionCheckUpdates.setObjectName(_fromUtf8("actionCheckUpdates"))
|
||||
self.actionDonate = QtGui.QAction(MainWindow)
|
||||
self.actionDonate.setObjectName(_fromUtf8("actionDonate"))
|
||||
self.actionOpen_project = QtGui.QAction(MainWindow)
|
||||
self.actionOpen_project.setObjectName(_fromUtf8("actionOpen_project"))
|
||||
self.actionSave_project = QtGui.QAction(MainWindow)
|
||||
self.actionSave_project.setObjectName(_fromUtf8("actionSave_project"))
|
||||
self.menuEdit.addAction(self.actionOptions)
|
||||
self.menuFile.addAction(self.actionOpen_project)
|
||||
self.menuFile.addAction(self.actionSave_project)
|
||||
self.menuFile.addAction(self.actionSave)
|
||||
self.menuFile.addAction(self.actionQuit)
|
||||
self.menuHelp.addAction(self.actionAbout)
|
||||
self.menuHelp.addAction(self.actionHelp)
|
||||
self.menuHelp.addAction(self.actionDebug)
|
||||
self.menuHelp.addAction(self.actionCheckUpdates)
|
||||
self.menubar.addAction(self.menuFile.menuAction())
|
||||
self.menubar.addAction(self.menuEdit.menuAction())
|
||||
self.menubar.addAction(self.menuHelp.menuAction())
|
||||
self.label.setBuddy(self.urlinput)
|
||||
|
||||
self.retranslateUi(MainWindow)
|
||||
QtCore.QMetaObject.connectSlotsByName(MainWindow)
|
||||
|
||||
def retranslateUi(self, MainWindow):
|
||||
MainWindow.setWindowTitle(_("LinkChecker"))
|
||||
self.label.setText(_("URL:"))
|
||||
self.controlButton.setToolTip(_("Start checking the given URL."))
|
||||
self.controlButton.setText(QtGui.QApplication.translate("MainWindow", "Start", "Start checking URL", QtGui.QApplication.UnicodeUTF8))
|
||||
self.label_29.setText(_("URLs: "))
|
||||
self.label_32.setText(_("active"))
|
||||
self.label_active.setText(_("0"))
|
||||
self.label_30.setText(_("queued"))
|
||||
self.label_queued.setText(_("0"))
|
||||
self.label_28.setText(_("checked"))
|
||||
self.label_checked.setText(_("0"))
|
||||
self.label_15.setText(_("Info:"))
|
||||
self.label_busy.setText(_("-"))
|
||||
self.url_properties.setTitle(_("URL properties"))
|
||||
self.label_2.setText(_("URL"))
|
||||
self.label_3.setText(_("Name"))
|
||||
self.label_4.setText(_("Parent URL"))
|
||||
self.label_5.setText(_("Base"))
|
||||
self.label_7.setText(_("Check time"))
|
||||
self.label_8.setText(_("D/L time"))
|
||||
self.label_9.setText(_("Size"))
|
||||
self.label_10.setText(_("Info"))
|
||||
self.label_11.setText(_("Warning"))
|
||||
self.label_12.setText(_("Result"))
|
||||
self.label_16.setText(_("Modified"))
|
||||
self.groupBox.setTitle(_("Check results"))
|
||||
self.label_24.setText(_("Valid URLs"))
|
||||
self.label_26.setText(_("Warnings"))
|
||||
self.label_25.setText(_("Invalid URLs"))
|
||||
self.groupBox_3.setTitle(_("Content type statistics"))
|
||||
self.label_6.setText(_("Image"))
|
||||
self.label_13.setText(_("Text"))
|
||||
self.label_27.setText(_("Application"))
|
||||
self.label_17.setText(_("Audio"))
|
||||
self.label_21.setText(_("Video"))
|
||||
self.label_23.setText(_("Other"))
|
||||
self.label_22.setText(_("Mail"))
|
||||
self.groupBox_2.setTitle(_("URL statistics"))
|
||||
self.label_18.setText(_("Min. length"))
|
||||
self.label_20.setText(_("Avg. length"))
|
||||
self.label_19.setText(_("Max. length"))
|
||||
self.menuEdit.setTitle(_("&Edit"))
|
||||
self.menuFile.setTitle(_("&File"))
|
||||
self.menuHelp.setTitle(_("&Help"))
|
||||
self.actionAbout.setText(_("A&bout"))
|
||||
self.actionAbout.setIconText(_("About"))
|
||||
self.actionHelp.setText(_("&Help"))
|
||||
self.actionHelp.setIconText(_("Help"))
|
||||
self.actionViewOnline.setText(_("View online"))
|
||||
self.actionViewOnline.setToolTip(_("View URL online"))
|
||||
self.actionOptions.setText(_("&Options"))
|
||||
self.actionOptions.setIconText(_("Options"))
|
||||
self.actionCopyToClipboard.setText(_("Copy to clipboard"))
|
||||
self.actionCopyToClipboard.setToolTip(_("Copy URL to clipboard"))
|
||||
self.actionCopyToClipboard.setShortcut(_("Ctrl+C"))
|
||||
self.actionViewParentOnline.setText(_("View parent online"))
|
||||
self.actionViewParentOnline.setToolTip(_("View parent URL online"))
|
||||
self.actionViewParentSource.setText(_("View parent source"))
|
||||
self.actionViewParentSource.setToolTip(_("View parent URL source"))
|
||||
self.actionDebug.setText(_("Show debug"))
|
||||
self.actionViewProperties.setText(_("View properties"))
|
||||
self.actionViewProperties.setToolTip(_("View URL properties"))
|
||||
self.actionSave.setText(_("Save &results..."))
|
||||
self.actionQuit.setText(_("&Quit"))
|
||||
self.actionQuit.setShortcut(_("Ctrl+Q"))
|
||||
self.actionCheckUpdates.setText(_("Check for updates"))
|
||||
self.actionDonate.setText(_("Donate"))
|
||||
self.actionOpen_project.setText(_("&Open project..."))
|
||||
self.actionOpen_project.setIconText(_("Open project"))
|
||||
self.actionOpen_project.setShortcut(_("Ctrl+O"))
|
||||
self.actionSave_project.setText(_("&Save project..."))
|
||||
self.actionSave_project.setShortcut(_("Ctrl+S"))
|
||||
|
||||
from lineedit import LineEdit
|
||||
import linkchecker_rc
|
||||
|
|
@ -1,147 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Form implementation generated from reading ui file 'ui/options.ui'
|
||||
#
|
||||
# Created: Fri Feb 28 21:24:59 2014
|
||||
# by: PyQt4 UI code generator 4.9.3
|
||||
#
|
||||
# WARNING! All changes made in this file will be lost!
|
||||
|
||||
from PyQt4 import QtCore, QtGui
|
||||
|
||||
try:
|
||||
_fromUtf8 = QtCore.QString.fromUtf8
|
||||
except AttributeError:
|
||||
_fromUtf8 = lambda s: s
|
||||
|
||||
class Ui_Options(object):
|
||||
def setupUi(self, Options):
|
||||
Options.setObjectName(_fromUtf8("Options"))
|
||||
Options.resize(455, 550)
|
||||
Options.setMinimumSize(QtCore.QSize(400, 550))
|
||||
self.verticalLayout_3 = QtGui.QVBoxLayout(Options)
|
||||
self.verticalLayout_3.setObjectName(_fromUtf8("verticalLayout_3"))
|
||||
self.groupBox_2 = QtGui.QGroupBox(Options)
|
||||
self.groupBox_2.setObjectName(_fromUtf8("groupBox_2"))
|
||||
self.verticalLayout = QtGui.QVBoxLayout(self.groupBox_2)
|
||||
self.verticalLayout.setObjectName(_fromUtf8("verticalLayout"))
|
||||
self.widget = QtGui.QWidget(self.groupBox_2)
|
||||
self.widget.setObjectName(_fromUtf8("widget"))
|
||||
self.formLayout = QtGui.QFormLayout(self.widget)
|
||||
self.formLayout.setFieldGrowthPolicy(QtGui.QFormLayout.ExpandingFieldsGrow)
|
||||
self.formLayout.setMargin(0)
|
||||
self.formLayout.setObjectName(_fromUtf8("formLayout"))
|
||||
self.label = QtGui.QLabel(self.widget)
|
||||
self.label.setObjectName(_fromUtf8("label"))
|
||||
self.formLayout.setWidget(0, QtGui.QFormLayout.LabelRole, self.label)
|
||||
self.recursionlevel = QtGui.QSpinBox(self.widget)
|
||||
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Preferred)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.recursionlevel.sizePolicy().hasHeightForWidth())
|
||||
self.recursionlevel.setSizePolicy(sizePolicy)
|
||||
self.recursionlevel.setMinimumSize(QtCore.QSize(0, 25))
|
||||
self.recursionlevel.setMinimum(-1)
|
||||
self.recursionlevel.setMaximum(100)
|
||||
self.recursionlevel.setProperty("value", -1)
|
||||
self.recursionlevel.setObjectName(_fromUtf8("recursionlevel"))
|
||||
self.formLayout.setWidget(0, QtGui.QFormLayout.FieldRole, self.recursionlevel)
|
||||
self.label_2 = QtGui.QLabel(self.widget)
|
||||
self.label_2.setObjectName(_fromUtf8("label_2"))
|
||||
self.formLayout.setWidget(1, QtGui.QFormLayout.LabelRole, self.label_2)
|
||||
self.verbose = QtGui.QCheckBox(self.widget)
|
||||
self.verbose.setEnabled(True)
|
||||
self.verbose.setText(_fromUtf8(""))
|
||||
self.verbose.setObjectName(_fromUtf8("verbose"))
|
||||
self.formLayout.setWidget(1, QtGui.QFormLayout.FieldRole, self.verbose)
|
||||
self.label_4 = QtGui.QLabel(self.widget)
|
||||
self.label_4.setObjectName(_fromUtf8("label_4"))
|
||||
self.formLayout.setWidget(2, QtGui.QFormLayout.LabelRole, self.label_4)
|
||||
self.debug = QtGui.QCheckBox(self.widget)
|
||||
self.debug.setText(_fromUtf8(""))
|
||||
self.debug.setObjectName(_fromUtf8("debug"))
|
||||
self.formLayout.setWidget(2, QtGui.QFormLayout.FieldRole, self.debug)
|
||||
self.verticalLayout.addWidget(self.widget)
|
||||
spacerItem = QtGui.QSpacerItem(20, 10, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding)
|
||||
self.verticalLayout.addItem(spacerItem)
|
||||
self.label_5 = QtGui.QLabel(self.groupBox_2)
|
||||
self.label_5.setObjectName(_fromUtf8("label_5"))
|
||||
self.verticalLayout.addWidget(self.label_5)
|
||||
self.warninglines = QtGui.QPlainTextEdit(self.groupBox_2)
|
||||
self.warninglines.setMaximumSize(QtCore.QSize(16777215, 150))
|
||||
self.warninglines.setObjectName(_fromUtf8("warninglines"))
|
||||
self.verticalLayout.addWidget(self.warninglines)
|
||||
self.label_6 = QtGui.QLabel(self.groupBox_2)
|
||||
self.label_6.setObjectName(_fromUtf8("label_6"))
|
||||
self.verticalLayout.addWidget(self.label_6)
|
||||
self.ignorelines = QtGui.QPlainTextEdit(self.groupBox_2)
|
||||
self.ignorelines.setMaximumSize(QtCore.QSize(16777215, 150))
|
||||
self.ignorelines.setObjectName(_fromUtf8("ignorelines"))
|
||||
self.verticalLayout.addWidget(self.ignorelines)
|
||||
self.verticalLayout_3.addWidget(self.groupBox_2)
|
||||
self.groupBox = QtGui.QGroupBox(Options)
|
||||
self.groupBox.setObjectName(_fromUtf8("groupBox"))
|
||||
self.verticalLayout_2 = QtGui.QVBoxLayout(self.groupBox)
|
||||
self.verticalLayout_2.setObjectName(_fromUtf8("verticalLayout_2"))
|
||||
self.label_3 = QtGui.QLabel(self.groupBox)
|
||||
self.label_3.setWordWrap(True)
|
||||
self.label_3.setObjectName(_fromUtf8("label_3"))
|
||||
self.verticalLayout_2.addWidget(self.label_3)
|
||||
spacerItem1 = QtGui.QSpacerItem(20, 10, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding)
|
||||
self.verticalLayout_2.addItem(spacerItem1)
|
||||
self.user_config_filename = QtGui.QLabel(self.groupBox)
|
||||
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Preferred)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.user_config_filename.sizePolicy().hasHeightForWidth())
|
||||
self.user_config_filename.setSizePolicy(sizePolicy)
|
||||
self.user_config_filename.setFrameShape(QtGui.QFrame.NoFrame)
|
||||
self.user_config_filename.setLineWidth(0)
|
||||
self.user_config_filename.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter)
|
||||
self.user_config_filename.setWordWrap(True)
|
||||
self.user_config_filename.setMargin(0)
|
||||
self.user_config_filename.setTextInteractionFlags(QtCore.Qt.TextSelectableByMouse)
|
||||
self.user_config_filename.setObjectName(_fromUtf8("user_config_filename"))
|
||||
self.verticalLayout_2.addWidget(self.user_config_filename)
|
||||
self.user_config_button = QtGui.QPushButton(self.groupBox)
|
||||
self.user_config_button.setEnabled(False)
|
||||
self.user_config_button.setToolTip(_fromUtf8(""))
|
||||
self.user_config_button.setObjectName(_fromUtf8("user_config_button"))
|
||||
self.verticalLayout_2.addWidget(self.user_config_button)
|
||||
self.verticalLayout_3.addWidget(self.groupBox)
|
||||
spacerItem2 = QtGui.QSpacerItem(20, 10, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding)
|
||||
self.verticalLayout_3.addItem(spacerItem2)
|
||||
self.widget_2 = QtGui.QWidget(Options)
|
||||
self.widget_2.setObjectName(_fromUtf8("widget_2"))
|
||||
self.horizontalLayout = QtGui.QHBoxLayout(self.widget_2)
|
||||
self.horizontalLayout.setMargin(0)
|
||||
self.horizontalLayout.setObjectName(_fromUtf8("horizontalLayout"))
|
||||
self.closeButton = QtGui.QPushButton(self.widget_2)
|
||||
self.closeButton.setObjectName(_fromUtf8("closeButton"))
|
||||
self.horizontalLayout.addWidget(self.closeButton)
|
||||
spacerItem3 = QtGui.QSpacerItem(317, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum)
|
||||
self.horizontalLayout.addItem(spacerItem3)
|
||||
self.verticalLayout_3.addWidget(self.widget_2)
|
||||
|
||||
self.retranslateUi(Options)
|
||||
QtCore.QMetaObject.connectSlotsByName(Options)
|
||||
|
||||
def retranslateUi(self, Options):
|
||||
Options.setWindowTitle(_("Options"))
|
||||
self.groupBox_2.setTitle(_("Checking options"))
|
||||
self.label.setToolTip(_("Check recursively all links up to given depth. A negative depth will enable infinite recursion."))
|
||||
self.label.setText(_("Recursive depth"))
|
||||
self.recursionlevel.setToolTip(_("Check recursively all links up to given depth. A negative depth will enable infinite recursion."))
|
||||
self.label_2.setToolTip(_("Log all checked URLs once. Default is to log only errors and warnings."))
|
||||
self.label_2.setText(_("Verbose output"))
|
||||
self.verbose.setToolTip(_("Log all checked URLs once. Default is to log only errors and warnings."))
|
||||
self.label_4.setText(_("Debug"))
|
||||
self.label_5.setText(_("Warn when one of these strings are found (one per line):"))
|
||||
self.label_6.setText(_("Ignore URLs matching one of these patterns (one per line):"))
|
||||
self.groupBox.setTitle(_("Configuration file"))
|
||||
self.label_3.setText(_("The configuration file holds advanced options and can be edited with an integrated text editor."))
|
||||
self.user_config_filename.setToolTip(_("Overrides system wide configuration file settings."))
|
||||
self.user_config_filename.setText(_("/home/user/.linkchecker/linkcheckerrc"))
|
||||
self.user_config_button.setText(_("Edit"))
|
||||
self.closeButton.setText(_("Close"))
|
||||
|
||||
|
|
@ -1,73 +0,0 @@
|
|||
# -*- coding: iso-8859-1 -*-
|
||||
# Copyright (C) 2009-2014 Bastian Kleineidam
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along
|
||||
# with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
from logging import Handler
|
||||
from ..logger import _Logger
|
||||
|
||||
|
||||
class GuiLogHandler (Handler, object):
|
||||
"""Delegate log messages to the UI."""
|
||||
|
||||
def __init__ (self, signal):
|
||||
"""Save widget."""
|
||||
super(GuiLogHandler, self).__init__()
|
||||
self.signal = signal
|
||||
|
||||
def emit (self, record):
|
||||
"""Emit a record. It gets logged in the debug widget."""
|
||||
self.signal.emit(self.format(record))
|
||||
|
||||
|
||||
class SignalLogger (_Logger):
|
||||
"""Use Qt signals for logged URLs and statistics."""
|
||||
|
||||
LoggerName = "gui"
|
||||
|
||||
def __init__ (self, **args):
|
||||
"""Store signals for URL and statistic data."""
|
||||
super(SignalLogger, self).__init__(**args)
|
||||
self.log_url_signal = args["signal"]
|
||||
self.log_stats_signal = args["stats"]
|
||||
|
||||
def start_fileoutput (self):
|
||||
"""Override fileoutput handling of base class."""
|
||||
pass
|
||||
|
||||
def close_fileoutput (self):
|
||||
"""Override fileoutput handling of base class."""
|
||||
pass
|
||||
|
||||
def log_url (self, url_data):
|
||||
"""Emit URL data which gets logged in the main window."""
|
||||
self.log_url_signal.emit(url_data)
|
||||
|
||||
def end_output (self, **kwargs):
|
||||
"""Emit statistic data which gets logged in the main window."""
|
||||
self.stats.downloaded_bytes = kwargs.get("downloaded_bytes")
|
||||
self.log_stats_signal.emit(self.stats)
|
||||
|
||||
|
||||
class StatusLogger (object):
|
||||
"""GUI status logger, signaling to progress labels."""
|
||||
|
||||
def __init__ (self, signal):
|
||||
"""Store given signal object."""
|
||||
self.signal = signal
|
||||
|
||||
def log_status (self, checked, in_progress, queued, duration, num_urls):
|
||||
"""Emit signal with given status information."""
|
||||
self.signal.emit(checked, in_progress, queued, duration, num_urls)
|
||||
|
|
@ -1,110 +0,0 @@
|
|||
# -*- coding: iso-8859-1 -*-
|
||||
# Copyright (C) 2009-2014 Bastian Kleineidam
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along
|
||||
# with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
import os
|
||||
from PyQt4 import QtGui
|
||||
from .linkchecker_ui_options import Ui_Options
|
||||
from .editor import EditorWindow
|
||||
from ..fileutil import is_writable
|
||||
from .. import configuration
|
||||
|
||||
|
||||
class LinkCheckerOptions (QtGui.QDialog, Ui_Options):
|
||||
"""Hold options for current URL to check."""
|
||||
|
||||
def __init__ (self, parent=None):
|
||||
"""Reset all options and initialize the editor window."""
|
||||
super(LinkCheckerOptions, self).__init__(parent)
|
||||
self.setupUi(self)
|
||||
self.editor = EditorWindow(self)
|
||||
self.closeButton.clicked.connect(self.close)
|
||||
self.user_config_button.clicked.connect(self.edit_user_config)
|
||||
self.reset()
|
||||
|
||||
def reset (self):
|
||||
"""Reset GUI and config options."""
|
||||
self.user_config = configuration.get_user_config()
|
||||
self.reset_gui_options()
|
||||
self.reset_config_options()
|
||||
|
||||
def reset_gui_options (self):
|
||||
"""Reset GUI options to default values."""
|
||||
self.recursionlevel.setValue(-1)
|
||||
self.verbose.setChecked(False)
|
||||
self.debug.setChecked(False)
|
||||
self.warninglines.setPlainText(u"")
|
||||
self.ignorelines.setPlainText(u"")
|
||||
|
||||
def reset_config_options (self):
|
||||
"""Reset configuration file edit buttons."""
|
||||
self.user_config_writable = is_writable(self.user_config)
|
||||
set_edit_button(self.user_config, self.user_config_button,
|
||||
self.user_config_filename, self.user_config_writable)
|
||||
|
||||
def edit_user_config (self):
|
||||
"""Show editor for user specific configuration file."""
|
||||
return start_editor(self.user_config, self.user_config_writable,
|
||||
self.editor)
|
||||
|
||||
def get_options (self):
|
||||
"""Return option data as dictionary."""
|
||||
return dict(
|
||||
debug=self.debug.isChecked(),
|
||||
verbose=self.verbose.isChecked(),
|
||||
recursionlevel=self.recursionlevel.value(),
|
||||
warninglines=unicode(self.warninglines.toPlainText()),
|
||||
ignorelines=unicode(self.ignorelines.toPlainText()),
|
||||
)
|
||||
|
||||
def set_options (self, data):
|
||||
"""Set GUI options from given data."""
|
||||
if data.get("debug") is not None:
|
||||
self.debug.setChecked(data["debug"])
|
||||
if data.get("verbose") is not None:
|
||||
self.verbose.setChecked(data["verbose"])
|
||||
if data.get("recursionlevel") is not None:
|
||||
self.recursionlevel.setValue(data["recursionlevel"])
|
||||
if data.get("warninglines") is not None:
|
||||
self.warninglines.setPlainText(data["warninglines"])
|
||||
if data.get("ignorelines") is not None:
|
||||
self.ignorelines.setPlainText(data["ignorelines"])
|
||||
|
||||
|
||||
def start_editor (filename, writable, editor):
|
||||
"""Start editor for given filename."""
|
||||
if not os.path.isfile(filename):
|
||||
# file vanished
|
||||
return
|
||||
editor.load(filename)
|
||||
# all config files are in INI format
|
||||
editor.setContentType("text/plain+ini")
|
||||
editor.editor.setReadOnly(not writable)
|
||||
editor.show()
|
||||
|
||||
|
||||
def set_edit_button (filename, button, label, writable):
|
||||
"""Update edit button depending on writable flag of file."""
|
||||
label.setText(filename)
|
||||
if os.path.isfile(filename):
|
||||
button.setEnabled(True)
|
||||
if writable:
|
||||
button.setText(_(u"Edit"))
|
||||
else:
|
||||
button.setText(_(u"Read"))
|
||||
else:
|
||||
button.setEnabled(False)
|
||||
button.setText(_(u"File not found"))
|
||||
|
|
@ -1,205 +0,0 @@
|
|||
# -*- coding: iso-8859-1 -*-
|
||||
# Copyright (C) 2012-2014 Bastian Kleineidam
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along
|
||||
# with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
import re
|
||||
import os
|
||||
import shutil
|
||||
from PyQt4 import QtGui
|
||||
from ..configuration import get_user_config, confparse
|
||||
from ..url import url_split
|
||||
from ..fileutil import is_readable, is_writable
|
||||
|
||||
ProjectExt = ".lcp"
|
||||
ProjectFilter = _("LinkChecker project (*%(ext)s)") % dict(ext=ProjectExt)
|
||||
|
||||
|
||||
class ProjectParser (confparse.LCConfigParser):
|
||||
|
||||
def __init__ (self, config, gui_options, urlinput):
|
||||
super(ProjectParser, self).__init__(config)
|
||||
# has set_options(data) function
|
||||
self.gui_options = gui_options
|
||||
# has setText(url) function
|
||||
self.urlinput = urlinput
|
||||
|
||||
def read (self, files):
|
||||
super(ProjectParser, self).read(files)
|
||||
self.read_project_config()
|
||||
self.read_gui_config()
|
||||
|
||||
def read_project_config(self):
|
||||
section = "project"
|
||||
if not self.has_section(section):
|
||||
return
|
||||
option = "url"
|
||||
if self.has_option(section, option):
|
||||
url = self.get(section, option)
|
||||
self.urlinput.setText(url)
|
||||
else:
|
||||
self.urlinput.setText(u"")
|
||||
|
||||
def read_gui_config(self):
|
||||
section = "gui"
|
||||
if not self.has_section(section):
|
||||
return
|
||||
data = {}
|
||||
option = "debug"
|
||||
if self.has_option(section, option):
|
||||
data[option] = self.getboolean(section, option)
|
||||
option = "verbose"
|
||||
if self.has_option(section, option):
|
||||
data[option] = self.getboolean(section, option)
|
||||
option = "recursionlevel"
|
||||
if self.has_option(section, option):
|
||||
data[option] = self.getint(section, option)
|
||||
option = "warninglines"
|
||||
if self.has_option(section, option):
|
||||
data[option] = self.get(section, option)
|
||||
option = "ignorelines"
|
||||
if self.has_option(section, option):
|
||||
data[option] = self.get(section, option)
|
||||
self.gui_options.set_options(data)
|
||||
|
||||
def write (self, fp):
|
||||
"""Write project configuration to given file object."""
|
||||
self.write_project_config()
|
||||
self.write_gui_config()
|
||||
super(ProjectParser, self).write(fp)
|
||||
|
||||
def write_project_config(self):
|
||||
"""Write project section configuration."""
|
||||
section = "project"
|
||||
self.add_section(section)
|
||||
self.set(section, "url", self.urlinput.text())
|
||||
|
||||
def write_gui_config(self):
|
||||
"""Write gui section configuration."""
|
||||
section = "gui"
|
||||
self.add_section(section)
|
||||
for key, value in self.gui_options.get_options().items():
|
||||
self.set(section, key, value)
|
||||
|
||||
|
||||
def url_to_filename(url, extension):
|
||||
value = unicode(url)
|
||||
# filter host and document
|
||||
parts = url_split(url)
|
||||
value = parts[1]+parts[3]
|
||||
# normalize
|
||||
import unicodedata
|
||||
value = unicodedata.normalize('NFKD', value).encode('ascii', 'ignore')
|
||||
# replace non-alpha characters and convert to lowercase
|
||||
value = re.sub('[^\w-]+', '_', value).strip().lower()
|
||||
# add extension
|
||||
return value + extension
|
||||
|
||||
|
||||
def saveproject(parent, url):
|
||||
"""Save a project file."""
|
||||
try:
|
||||
msg = saveproject_msg(parent, url)
|
||||
except Exception as errmsg:
|
||||
msg = str(errmsg)
|
||||
parent.set_statusmsg(msg)
|
||||
|
||||
def saveproject_msg(parent, url):
|
||||
"""Save a project file and return status message."""
|
||||
title = _("Save LinkChecker project")
|
||||
func = QtGui.QFileDialog.getSaveFileName
|
||||
suggestedname = url_to_filename(url, ProjectExt)
|
||||
res = func(parent, title, suggestedname, ProjectFilter)
|
||||
if not res:
|
||||
# user canceled
|
||||
return _("Canceled saving a project file.")
|
||||
filename = unicode(res)
|
||||
d = dict(filename=filename)
|
||||
if not is_writable(filename):
|
||||
return _("Could not write project file %(filename)s.") % d
|
||||
user_config = get_user_config()
|
||||
if is_readable(user_config):
|
||||
# Copy user config to filename since this is the current
|
||||
# configuration.
|
||||
# This way it is not necessary to write the parent.config
|
||||
# dictionary back to a file.
|
||||
shutil.copy(user_config, filename)
|
||||
filter_comments = True
|
||||
else:
|
||||
# use default config (ie. do not write anything)
|
||||
filter_comments = False
|
||||
write_header(filename, filter_comments)
|
||||
parser = ProjectParser(parent.config, parent.options, parent.urlinput)
|
||||
with open(filename, 'a') as fp:
|
||||
parser.write(fp)
|
||||
return _("Project file %(filename)s saved successfully.") % d
|
||||
|
||||
|
||||
def write_header(filename, filter_comments):
|
||||
"""Write header and filter comment lines if file already exists."""
|
||||
lines = [
|
||||
'# This is a generated LinkChecker project file. Do not edit'+os.linesep,
|
||||
]
|
||||
if filter_comments:
|
||||
with open(filename, 'r') as fp:
|
||||
for line in fp:
|
||||
if not line.lstrip().startswith((';', '#')):
|
||||
lines.append(line)
|
||||
with open(filename, 'w') as fp:
|
||||
for line in lines:
|
||||
fp.write(line)
|
||||
|
||||
|
||||
def openproject (parent):
|
||||
"""Select and load a project file."""
|
||||
try:
|
||||
msg = openproject_msg(parent)
|
||||
except Exception as errmsg:
|
||||
msg = str(errmsg)
|
||||
parent.set_statusmsg(msg)
|
||||
|
||||
|
||||
def openproject_msg(parent):
|
||||
"""Select and load a project file. Returns message to display
|
||||
which indicates if file has been loaded successful."""
|
||||
title = _("Open LinkChecker project")
|
||||
func = QtGui.QFileDialog.getOpenFileName
|
||||
directory = ""
|
||||
filename = func(parent, title, directory, ProjectFilter)
|
||||
if not filename:
|
||||
# user canceled
|
||||
return _("Canceled opening a project file.")
|
||||
if not is_readable(filename):
|
||||
return _("Could not read project file %(filename)s.") % dict(filename=filename)
|
||||
return loadproject(filename, parent.config, parent.options, parent.urlinput)
|
||||
|
||||
|
||||
def loadproject(parent, filename):
|
||||
"""Load a project file."""
|
||||
try:
|
||||
msg = loadproject_msg(parent, filename)
|
||||
except Exception as errmsg:
|
||||
args = dict(filename=filename, err=errmsg)
|
||||
msg = _("Could not load project %(filename)s: %(err)s") % args
|
||||
parent.set_statusmsg(msg)
|
||||
|
||||
|
||||
def loadproject_msg(parent, filename):
|
||||
"""Load a project file. Returns message to display which indicates if
|
||||
file has been loaded successful."""
|
||||
parser = ProjectParser(parent.config, parent.options, parent.urlinput)
|
||||
parser.read([filename])
|
||||
d = dict(filename=filename)
|
||||
return _("Project file %(filename)s loaded successfully.") % d
|
||||
|
||||
|
|
@ -1,80 +0,0 @@
|
|||
# -*- coding: iso-8859-1 -*-
|
||||
# Copyright (C) 2010-2014 Bastian Kleineidam
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along
|
||||
# with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
import os
|
||||
from .. import strformat
|
||||
|
||||
|
||||
def set_properties (widget, data):
|
||||
"""Write URL data values into widget text fields."""
|
||||
if data.base_url and data.url:
|
||||
widget.prop_url.setText(u'<a href="%(url)s">%(base_url)s</a>' % \
|
||||
dict(url=data.url, base_url=data.base_url))
|
||||
else:
|
||||
widget.prop_url.setText(u"")
|
||||
widget.prop_name.setText(data.name)
|
||||
if data.parent_url:
|
||||
widget.prop_parenturl.setText(u'<a href="%(url)s">%(url)s</a>' % \
|
||||
dict(url=data.parent_url))
|
||||
else:
|
||||
widget.prop_parenturl.setText(u"")
|
||||
widget.prop_base.setText(data.base_ref)
|
||||
widget.prop_checktime.setText(_("%.3f seconds") % data.checktime)
|
||||
if data.dltime >= 0:
|
||||
widget.prop_dltime.setText(_("%.3f seconds") % data.dltime)
|
||||
else:
|
||||
widget.prop_dltime.setText(u"")
|
||||
if data.size >= 0:
|
||||
widget.prop_size.setText(strformat.strsize(data.size))
|
||||
else:
|
||||
widget.prop_size.setText(u"")
|
||||
if data.modified:
|
||||
widget.prop_modified.setText(data.modified.isoformat(" "))
|
||||
else:
|
||||
widget.prop_modified.setText(u"")
|
||||
widget.prop_info.setText(wrap(data.info, 65))
|
||||
warning_msgs = [x[1] for x in data.warnings]
|
||||
widget.prop_warning.setText(wrap(warning_msgs, 65))
|
||||
if data.valid:
|
||||
result = u"Valid"
|
||||
else:
|
||||
result = u"Error"
|
||||
if data.result:
|
||||
result += u": %s" % data.result
|
||||
widget.prop_result.setText(result)
|
||||
|
||||
|
||||
def clear_properties (widget):
|
||||
"""Reset URL data values in widget text fields."""
|
||||
widget.prop_url.setText(u"")
|
||||
widget.prop_name.setText(u"")
|
||||
widget.prop_parenturl.setText(u"")
|
||||
widget.prop_base.setText(u"")
|
||||
widget.prop_checktime.setText(u"")
|
||||
widget.prop_dltime.setText(u"")
|
||||
widget.prop_size.setText(u"")
|
||||
widget.prop_info.setText(u"")
|
||||
widget.prop_warning.setText(u"")
|
||||
widget.prop_result.setText(u"")
|
||||
|
||||
|
||||
def wrap (lines, width):
|
||||
"""Format lines with given line-width."""
|
||||
sep = os.linesep+os.linesep
|
||||
text = sep.join(lines)
|
||||
kwargs = dict(break_long_words=False, break_on_hyphens=False)
|
||||
return strformat.wrap(text, width, **kwargs)
|
||||
|
|
@ -1,62 +0,0 @@
|
|||
# refresh media files
|
||||
|
||||
# base directory of oxygen icon set checkout
|
||||
OXYGEN = $(HOME)/src/oxygen-gitsvn/16x16
|
||||
|
||||
ICONS = \
|
||||
cancel.png \
|
||||
online.png \
|
||||
options.png \
|
||||
preferences.png \
|
||||
save.png \
|
||||
start.png \
|
||||
stop.png \
|
||||
about.png \
|
||||
help.png \
|
||||
exit.png \
|
||||
copy.png \
|
||||
clear.png
|
||||
|
||||
all: $(ICONS)
|
||||
|
||||
app.png: $(OXYGEN)/categories/applications-development-web.png
|
||||
cp $< $@
|
||||
|
||||
save.png: $(OXYGEN)/actions/document-save-as.png
|
||||
cp $< $@
|
||||
|
||||
start.png: $(OXYGEN)/actions/media-playback-start.png
|
||||
cp $< $@
|
||||
|
||||
stop.png: $(OXYGEN)/actions/media-playback-stop.png
|
||||
cp $< $@
|
||||
|
||||
cancel.png: $(OXYGEN)/actions/process-stop.png
|
||||
cp $< $@
|
||||
|
||||
about.png: $(OXYGEN)/actions/help-about.png
|
||||
cp $< $@
|
||||
|
||||
help.png: $(OXYGEN)/actions/help-contents.png
|
||||
cp $< $@
|
||||
|
||||
exit.png: $(OXYGEN)/actions/application-exit.png
|
||||
cp $< $@
|
||||
|
||||
copy.png: $(OXYGEN)/actions/edit-copy.png
|
||||
cp $< $@
|
||||
|
||||
online.png: $(OXYGEN)/actions/document-open-remote.png
|
||||
cp $< $@
|
||||
|
||||
options.png: $(OXYGEN)/categories/preferences-system-network.png
|
||||
cp $< $@
|
||||
|
||||
preferences.png: $(OXYGEN)/categories/preferences-other.png
|
||||
cp $< $@
|
||||
|
||||
clear.png: $(OXYGEN)/actions/edit-clear-locationbar-rtl.png
|
||||
cp $< $@
|
||||
|
||||
clean:
|
||||
rm -f $(ICONS)
|
||||
|
Before Width: | Height: | Size: 803 B |
|
Before Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 444 B |
|
Before Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 722 B |
|
Before Width: | Height: | Size: 644 B |
|
Before Width: | Height: | Size: 485 B |
|
Before Width: | Height: | Size: 842 B |
|
Before Width: | Height: | Size: 684 B |
|
|
@ -1,19 +0,0 @@
|
|||
<RCC>
|
||||
<qresource prefix="icons">
|
||||
<file>clear.png</file>
|
||||
<file>arrow_down.png</file>
|
||||
<file>busy.gif</file>
|
||||
<file>save.png</file>
|
||||
<file>copy.png</file>
|
||||
<file>about.png</file>
|
||||
<file>help.png</file>
|
||||
<file>exit.png</file>
|
||||
<file>online.png</file>
|
||||
<file>cancel.png</file>
|
||||
<file>app.png</file>
|
||||
<file>options.png</file>
|
||||
<file>preferences.png</file>
|
||||
<file>start.png</file>
|
||||
<file>stop.png</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
Before Width: | Height: | Size: 842 B |
|
Before Width: | Height: | Size: 969 B |
|
Before Width: | Height: | Size: 950 B |
|
Before Width: | Height: | Size: 839 B |
|
Before Width: | Height: | Size: 501 B |
|
Before Width: | Height: | Size: 499 B |
|
|
@ -1,89 +0,0 @@
|
|||
# -*- coding: iso-8859-1 -*-
|
||||
# Copyright (C) 2011-2014 Bastian Kleineidam
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along
|
||||
# with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
from PyQt4 import QtCore
|
||||
|
||||
EmptyQVariant = QtCore.QVariant()
|
||||
|
||||
|
||||
class RecentDocumentModel(QtCore.QAbstractListModel):
|
||||
"""Model class for list of recent documents."""
|
||||
|
||||
def __init__ (self, parent=None, documents=[], maxentries=10):
|
||||
"""Set document list."""
|
||||
super(RecentDocumentModel, self).__init__(parent)
|
||||
self.maxentries = maxentries
|
||||
self.documents = documents[:maxentries]
|
||||
|
||||
def rowCount (self, parent=QtCore.QModelIndex()):
|
||||
"""Return number of documents."""
|
||||
return len(self.documents)
|
||||
|
||||
def index (self, row, column=0, parent=QtCore.QModelIndex()):
|
||||
"""Return index of document in given row."""
|
||||
return self.createIndex(row, column)
|
||||
|
||||
def data (self, index, role=QtCore.Qt.DisplayRole):
|
||||
"""Return data at given index for given role."""
|
||||
V = QtCore.QVariant
|
||||
if not index.isValid() or \
|
||||
not (0 <= index.row() < len(self.documents)) or \
|
||||
index.column() != 0:
|
||||
return EmptyQVariant
|
||||
if role == QtCore.Qt.DisplayRole:
|
||||
return V(self.documents[index.row()])
|
||||
return EmptyQVariant
|
||||
|
||||
def headerData (self, section, orientation, role):
|
||||
"""Return header column data for given parameters."""
|
||||
return EmptyQVariant
|
||||
|
||||
def flags (self, index):
|
||||
"""Return flags that given valid item index is enabled and
|
||||
selected."""
|
||||
if not index.isValid():
|
||||
return 0
|
||||
return QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsSelectable
|
||||
|
||||
def clear (self):
|
||||
"""Empty the document list."""
|
||||
self.beginResetModel()
|
||||
self.documents = []
|
||||
self.endResetModel()
|
||||
|
||||
def add_document (self, document):
|
||||
"""Add document to model."""
|
||||
if not document:
|
||||
return False
|
||||
assert isinstance(document, unicode)
|
||||
while document in self.documents:
|
||||
row = self.documents.index(document)
|
||||
self.beginRemoveRows(QtCore.QModelIndex(), row, row)
|
||||
del self.documents[row]
|
||||
self.endRemoveRows()
|
||||
while len(self.documents) >= self.maxentries:
|
||||
row = len(self.documents) - 1
|
||||
self.beginRemoveRows(QtCore.QModelIndex(), row, row)
|
||||
del self.documents[row]
|
||||
self.endRemoveRows()
|
||||
self.beginInsertRows(QtCore.QModelIndex(), 0, 0)
|
||||
self.documents.insert(0, document)
|
||||
self.endInsertRows()
|
||||
return True
|
||||
|
||||
def get_documents (self):
|
||||
"""Return copy of document list."""
|
||||
return self.documents[:]
|
||||
|
|
@ -1,159 +0,0 @@
|
|||
# -*- coding: iso-8859-1 -*-
|
||||
# Copyright (C) 2010-2014 Bastian Kleineidam
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along
|
||||
# with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
"""Read and store QSettings for this application."""
|
||||
|
||||
from PyQt4 import QtCore
|
||||
|
||||
|
||||
def save_point (qpoint):
|
||||
"""Ensure positive X and Y values of point."""
|
||||
qpoint.setX(max(0, qpoint.x()))
|
||||
qpoint.setY(max(0, qpoint.y()))
|
||||
return qpoint
|
||||
|
||||
|
||||
def save_size (qsize):
|
||||
"""Ensure minimum width and height values of the given size."""
|
||||
qsize.setWidth(max(400, qsize.width()))
|
||||
qsize.setHeight(max(400, qsize.height()))
|
||||
return qsize
|
||||
|
||||
|
||||
class Settings (object):
|
||||
"""Save and read GUI settings."""
|
||||
|
||||
def __init__ (self, base, appname):
|
||||
"""Initialize a QSettings object."""
|
||||
self.settings = QtCore.QSettings(base, appname)
|
||||
|
||||
def read_geometry (self):
|
||||
"""Return stored size and position of main window."""
|
||||
data = dict(size=None, pos=None)
|
||||
self.settings.beginGroup('mainwindow')
|
||||
if self.settings.contains('size'):
|
||||
data["size"] = save_size(self.settings.value('size').toSize())
|
||||
if self.settings.contains('pos'):
|
||||
data["pos"] = save_point(self.settings.value('pos').toPoint())
|
||||
self.settings.endGroup()
|
||||
return data
|
||||
|
||||
def save_geometry (self, data):
|
||||
"""Save size and position of main window."""
|
||||
size = save_size(data["size"])
|
||||
pos = save_point(data["pos"])
|
||||
self.settings.beginGroup('mainwindow')
|
||||
self.settings.setValue("size", QtCore.QVariant(size))
|
||||
self.settings.setValue("pos", QtCore.QVariant(pos))
|
||||
self.settings.endGroup()
|
||||
|
||||
def read_treeviewcols (self):
|
||||
"""Return widths of URL treeview columns."""
|
||||
data = dict(col1=200, col2=200, col3=150)
|
||||
self.settings.beginGroup('treeview')
|
||||
for key in ("col1", "col2", "col3"):
|
||||
if self.settings.contains(key):
|
||||
value, ok = self.settings.value(key).toInt()
|
||||
if ok:
|
||||
if value < 50:
|
||||
value = 50
|
||||
elif value > 500:
|
||||
value = 500
|
||||
data[key] = value
|
||||
self.settings.endGroup()
|
||||
return data
|
||||
|
||||
def save_treeviewcols (self, data):
|
||||
"""Save widths of URL treeview columns."""
|
||||
self.settings.beginGroup('treeview')
|
||||
for key in ("col1", "col2", "col3"):
|
||||
self.settings.setValue(key, QtCore.QVariant(data[key]))
|
||||
self.settings.endGroup()
|
||||
|
||||
def read_options (self):
|
||||
"""Return stored GUI options."""
|
||||
data = dict(debug=None, verbose=None,
|
||||
recursionlevel=None, warninglines=None, ignorelines=None)
|
||||
self.settings.beginGroup('output')
|
||||
for key in ("debug", "verbose"):
|
||||
if self.settings.contains(key):
|
||||
data[key] = self.settings.value(key).toBool()
|
||||
self.settings.endGroup()
|
||||
self.settings.beginGroup('checking')
|
||||
if self.settings.contains('recursionlevel'):
|
||||
value, ok = self.settings.value('recursionlevel').toInt()
|
||||
if ok:
|
||||
if value < -1:
|
||||
value = -1
|
||||
elif value > 100:
|
||||
# 100 is the maximum GUI option value
|
||||
value = 100
|
||||
else:
|
||||
value = -1
|
||||
data['recursionlevel'] = value
|
||||
if self.settings.contains('warninglines'):
|
||||
value = self.settings.value('warninglines').toString()
|
||||
data['warninglines'] = unicode(value)
|
||||
if self.settings.contains('ignorelines'):
|
||||
value = self.settings.value('ignorelines').toString()
|
||||
data['ignorelines'] = unicode(value)
|
||||
self.settings.endGroup()
|
||||
return data
|
||||
|
||||
def save_options (self, data):
|
||||
"""Save GUI options."""
|
||||
self.settings.beginGroup('output')
|
||||
for key in ("debug", "verbose"):
|
||||
self.settings.setValue(key, QtCore.QVariant(data[key]))
|
||||
self.settings.endGroup()
|
||||
self.settings.beginGroup('checking')
|
||||
for key in ("recursionlevel", "warninglines", "ignorelines"):
|
||||
self.settings.setValue(key, QtCore.QVariant(data[key]))
|
||||
self.settings.endGroup()
|
||||
|
||||
def read_recent_documents (self):
|
||||
"""Return list of recent documents."""
|
||||
self.settings.beginGroup('recent')
|
||||
data = self.settings.value('documents').toStringList()
|
||||
self.settings.endGroup()
|
||||
return [unicode(doc) for doc in data]
|
||||
|
||||
def save_recent_documents (self, data):
|
||||
"""Save list of recent documents."""
|
||||
self.settings.beginGroup('recent')
|
||||
self.settings.setValue('documents', QtCore.QVariant(data))
|
||||
self.settings.endGroup()
|
||||
|
||||
def read_misc(self):
|
||||
"""Get misc options."""
|
||||
data = dict(saveresultas=None)
|
||||
self.settings.beginGroup('misc')
|
||||
key = 'saveresultas'
|
||||
value = self.settings.value(key).toString()
|
||||
data[key] = unicode(value)
|
||||
self.settings.endGroup()
|
||||
return data
|
||||
|
||||
def save_misc(self, data):
|
||||
"""Save misc options."""
|
||||
self.settings.beginGroup('misc')
|
||||
key = 'saveresultas'
|
||||
self.settings.setValue(key, QtCore.QVariant(data[key]))
|
||||
self.settings.endGroup()
|
||||
|
||||
def sync (self):
|
||||
"""Synchronize QSettings object to disk."""
|
||||
self.settings.sync()
|
||||
|
|
@ -1,47 +0,0 @@
|
|||
# -*- coding: iso-8859-1 -*-
|
||||
# Copyright (C) 2010-2014 Bastian Kleineidam
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along
|
||||
# with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
from ..logger import ContentTypes
|
||||
|
||||
def set_statistics (widget, statistics):
|
||||
"""Set statistic information in given widget."""
|
||||
widget.stats_url_minlen.setText(u"%d" % statistics.min_url_length)
|
||||
widget.stats_url_maxlen.setText(u"%d" % statistics.max_url_length)
|
||||
widget.stats_url_avglen.setText(u"%d" % statistics.avg_url_length)
|
||||
widget.stats_valid_urls.setText(u"%d" % (statistics.number - statistics.errors))
|
||||
if statistics.errors > 0:
|
||||
color = '#aa0000'
|
||||
else:
|
||||
color = '#00aa00'
|
||||
style = "QLabel {font-weight:bold; color:%s;}" % color
|
||||
widget.stats_invalid_urls.setStyleSheet(style)
|
||||
widget.stats_invalid_urls.setText(u"%d" % statistics.errors)
|
||||
widget.stats_warnings.setText(u"%d" % statistics.warnings)
|
||||
for key, value in statistics.link_types.items():
|
||||
getattr(widget, "stats_content_%s"%key).setText(u"%d" % value)
|
||||
|
||||
|
||||
def clear_statistics (widget):
|
||||
"""Reset statistic information in given widget."""
|
||||
widget.stats_url_minlen.setText(u"")
|
||||
widget.stats_url_maxlen.setText(u"")
|
||||
widget.stats_url_avglen.setText(u"")
|
||||
widget.stats_valid_urls.setText(u"")
|
||||
widget.stats_invalid_urls.setText(u"")
|
||||
widget.stats_warnings.setText(u"")
|
||||
for key in ContentTypes:
|
||||
getattr(widget, "stats_content_%s"%key).setText(u"")
|
||||
|
|
@ -1,98 +0,0 @@
|
|||
# -*- coding: iso-8859-1 -*-
|
||||
# Copyright (C) 2011-2014 Bastian Kleineidam
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along
|
||||
# with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
from PyQt4 import QtCore, QtGui
|
||||
|
||||
|
||||
def format (color, style=''):
|
||||
"""Return a QTextCharFormat with the given attributes."""
|
||||
format = QtGui.QTextCharFormat()
|
||||
format.setForeground(getattr(QtCore.Qt, color))
|
||||
if 'bold' in style:
|
||||
format.setFontWeight(QtGui.QFont.Bold)
|
||||
if 'italic' in style:
|
||||
format.setFontItalic(True)
|
||||
return format
|
||||
|
||||
|
||||
class Highlighter (QtGui.QSyntaxHighlighter):
|
||||
"""Base class for all highlighters."""
|
||||
|
||||
def __init__ (self, document):
|
||||
"""Initialize rules and styles."""
|
||||
super(Highlighter, self).__init__(document)
|
||||
self.rules = []
|
||||
self.styles = {}
|
||||
|
||||
def highlightBlock(self, text):
|
||||
"""Highlight a text block."""
|
||||
for expression, format in self.rules:
|
||||
# get first match
|
||||
index = expression.indexIn(text)
|
||||
while index >= 0:
|
||||
length = expression.matchedLength()
|
||||
self.setFormat(index, length, format)
|
||||
# jump to next match
|
||||
index = expression.indexIn(text, index + length)
|
||||
self.setCurrentBlockState(0)
|
||||
|
||||
def addRule (self, pattern, style):
|
||||
"""Add a rule pattern with given style."""
|
||||
self.rules.append((QtCore.QRegExp(pattern), self.styles[style]))
|
||||
|
||||
|
||||
class XmlHighlighter (Highlighter):
|
||||
"""XML syntax highlighter."""
|
||||
|
||||
def __init__(self, document):
|
||||
"""Set XML syntax rules."""
|
||||
super(XmlHighlighter, self).__init__(document)
|
||||
self.styles.update({
|
||||
'keyword': format('darkBlue'),
|
||||
'attribute': format('darkGreen'),
|
||||
'comment': format('darkYellow'),
|
||||
'string': format('darkMagenta'),
|
||||
})
|
||||
# keywords
|
||||
for reg in ('/>', '>', '<!?[a-zA-Z0-9_]+'):
|
||||
self.addRule(reg, 'keyword')
|
||||
# attributes
|
||||
self.addRule(r"\b[A-Za-z0-9_]+(?=\s*\=)", 'attribute')
|
||||
# double-quoted string, possibly containing escape sequences
|
||||
self.addRule(r'"[^"\\]*(\\.[^"\\]*)*"', 'string')
|
||||
# single-quoted string, possibly containing escape sequences
|
||||
self.addRule(r"'[^'\\]*(\\.[^'\\]*)*'", 'string')
|
||||
# comments
|
||||
self.addRule(r"<!--[^>]*-->", 'comment')
|
||||
|
||||
# Treat HTML as XML
|
||||
HtmlHighlighter = XmlHighlighter
|
||||
|
||||
class IniHighlighter (Highlighter):
|
||||
"""INI syntax highlighter."""
|
||||
|
||||
def __init__(self, document):
|
||||
"""Set INI syntax rules."""
|
||||
super(IniHighlighter, self).__init__(document)
|
||||
self.styles.update({
|
||||
'section': format('darkBlue'),
|
||||
'property': format('darkGreen'),
|
||||
'comment': format('darkYellow'),
|
||||
})
|
||||
self.addRule(r'\b\[[a-zA-Z0-9_]+\]\b', 'section')
|
||||
self.addRule(r'\b[a-zA-Z0-9_]+\](?=\s*\=)', 'property')
|
||||
self.addRule(r'#[^\n]*', 'comment')
|
||||
|
|
@ -1,49 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>DebugDialog</class>
|
||||
<widget class="QDialog" name="DebugDialog">
|
||||
<property name="windowModality">
|
||||
<enum>Qt::ApplicationModal</enum>
|
||||
</property>
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>564</width>
|
||||
<height>547</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>LinkChecker debug log</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QFrame" name="frame">
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::StyledPanel</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Raised</enum>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<widget class="QPlainTextEdit" name="textEdit">
|
||||
<property name="undoRedoEnabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="plainText">
|
||||
<string notr="true"/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
|
|
@ -1,71 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>EditorDialog</class>
|
||||
<widget class="QDialog" name="EditorDialog">
|
||||
<property name="windowModality">
|
||||
<enum>Qt::ApplicationModal</enum>
|
||||
</property>
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>640</width>
|
||||
<height>600</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>LinkChecker source view</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<property name="margin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QMenuBar" name="menubar">
|
||||
<widget class="QMenu" name="menuFile">
|
||||
<property name="title">
|
||||
<string>&File</string>
|
||||
</property>
|
||||
<addaction name="actionSave"/>
|
||||
</widget>
|
||||
<addaction name="menuFile"/>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QFrame" name="frame">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::NoFrame</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Plain</enum>
|
||||
</property>
|
||||
<property name="lineWidth">
|
||||
<number>0</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
<action name="actionSave">
|
||||
<property name="text">
|
||||
<string>&Save</string>
|
||||
</property>
|
||||
<property name="shortcut">
|
||||
<string>Ctrl+S</string>
|
||||
</property>
|
||||
</action>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
|
|
@ -1,285 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>Options</class>
|
||||
<widget class="QDialog" name="Options">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>455</width>
|
||||
<height>550</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>400</width>
|
||||
<height>550</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Options</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox_2">
|
||||
<property name="title">
|
||||
<string>Checking options</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QWidget" name="widget" native="true">
|
||||
<layout class="QFormLayout" name="formLayout">
|
||||
<property name="fieldGrowthPolicy">
|
||||
<enum>QFormLayout::ExpandingFieldsGrow</enum>
|
||||
</property>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="toolTip">
|
||||
<string>Check recursively all links up to given depth. A negative depth will enable infinite recursion.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Recursive depth</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QSpinBox" name="recursionlevel">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>25</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Check recursively all links up to given depth. A negative depth will enable infinite recursion.</string>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>-1</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>100</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>-1</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="toolTip">
|
||||
<string>Log all checked URLs once. Default is to log only errors and warnings.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Verbose output</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QCheckBox" name="verbose">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Log all checked URLs once. Default is to log only errors and warnings.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
<string>Debug</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QCheckBox" name="debug">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>10</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_5">
|
||||
<property name="text">
|
||||
<string>Warn when one of these strings are found (one per line):</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPlainTextEdit" name="warninglines">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>150</height>
|
||||
</size>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_6">
|
||||
<property name="text">
|
||||
<string>Ignore URLs matching one of these patterns (one per line):</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPlainTextEdit" name="ignorelines">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>150</height>
|
||||
</size>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox">
|
||||
<property name="title">
|
||||
<string>Configuration file</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>The configuration file holds advanced options and can be edited with an integrated text editor.</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>10</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="user_config_filename">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Overrides system wide configuration file settings.</string>
|
||||
</property>
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::NoFrame</enum>
|
||||
</property>
|
||||
<property name="lineWidth">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>/home/user/.linkchecker/linkcheckerrc</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="margin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="textInteractionFlags">
|
||||
<set>Qt::TextSelectableByMouse</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="user_config_button">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Edit</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer_3">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>10</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QWidget" name="widget_2" native="true">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QPushButton" name="closeButton">
|
||||
<property name="text">
|
||||
<string>Close</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>317</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
|
|
@ -1,82 +0,0 @@
|
|||
# -*- coding: iso-8859-1 -*-
|
||||
# Copyright (C) 2011-2014 Bastian Kleineidam
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along
|
||||
# with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
from PyQt4 import QtCore, QtGui
|
||||
from .. import updater, configuration
|
||||
|
||||
|
||||
class UpdateThread (QtCore.QThread):
|
||||
"""Thread to check for updated versions."""
|
||||
|
||||
def reset (self):
|
||||
"""Reset version information."""
|
||||
self.result = self.value = None
|
||||
|
||||
def run (self):
|
||||
"""Check for updated version."""
|
||||
self.result, self.value = updater.check_update()
|
||||
|
||||
|
||||
class UpdateDialog (QtGui.QMessageBox):
|
||||
"""Dialog displaying results of an update check."""
|
||||
|
||||
def __init__ (self, parent=None):
|
||||
"""Initialize dialog and start background update thread."""
|
||||
super(UpdateDialog, self).__init__(parent)
|
||||
title = _('%(app)s update information') % dict(app=configuration.App)
|
||||
self.setWindowTitle(title)
|
||||
self.thread = UpdateThread()
|
||||
self.thread.finished.connect(self.update)
|
||||
|
||||
def reset (self):
|
||||
"""Reset dialog and restart update check."""
|
||||
self.thread.reset()
|
||||
self.thread.start()
|
||||
self.setIcon(QtGui.QMessageBox.Information)
|
||||
self.setText(_('Checking for updates...'))
|
||||
|
||||
def update (self):
|
||||
"""Display update thread result (which must be available)."""
|
||||
result, value = self.thread.result, self.thread.value
|
||||
if result:
|
||||
if value is None:
|
||||
# no update available: display info
|
||||
text = _('Congratulations: the latest version '
|
||||
'%(app)s is installed.')
|
||||
attrs = dict(app=configuration.App)
|
||||
else:
|
||||
version, url = value
|
||||
if url is None:
|
||||
# current version is newer than online version
|
||||
text = _('Detected local or development version %(currentversion)s. '
|
||||
'Available version of %(app)s is %(version)s.')
|
||||
else:
|
||||
# display update link
|
||||
text = _('A new version %(version)s of %(app)s is '
|
||||
'available for <a href="%(url)s">download</a>.')
|
||||
attrs = dict(version=version, app=configuration.AppName,
|
||||
url=url, currentversion=configuration.Version)
|
||||
else:
|
||||
# value is an error message or None if UpdateThread has been
|
||||
# terminated
|
||||
if value is None:
|
||||
value = _('update thread has been terminated')
|
||||
self.setIcon(QtGui.QMessageBox.Warning)
|
||||
text = _('An error occured while checking for an '
|
||||
'update of %(app)s: %(error)s.')
|
||||
attrs = dict(error=value, app=configuration.AppName)
|
||||
self.setText(text % attrs)
|
||||
|
|
@ -1,196 +0,0 @@
|
|||
# -*- coding: iso-8859-1 -*-
|
||||
# Copyright (C) 2010-2014 Bastian Kleineidam
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along
|
||||
# with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
import operator
|
||||
from PyQt4 import QtCore, QtGui
|
||||
from .. import strformat
|
||||
|
||||
|
||||
Headers = [_(u"Parent"), _(u"URL"), _(u"Name"), _(u"Result")]
|
||||
EmptyQVariant = QtCore.QVariant()
|
||||
|
||||
|
||||
class UrlItem (object):
|
||||
"""URL item storing info to be displayed."""
|
||||
|
||||
def __init__ (self, url_data):
|
||||
"""Save given URL data and initialize display and tooltip texts."""
|
||||
# url_data is of type CompactUrlData
|
||||
self.url_data = url_data
|
||||
# format display and tooltips
|
||||
self.init_display()
|
||||
self.init_tooltips()
|
||||
|
||||
def __getitem__ (self, key):
|
||||
"""Define easy index access (used for sorting):
|
||||
0: Parent URL
|
||||
1: URL
|
||||
2: URL name
|
||||
3: Result
|
||||
"""
|
||||
if not isinstance(key, int):
|
||||
raise TypeError("invalid index %r" % key)
|
||||
if key == 0:
|
||||
return (self.url_data.parent_url, self.url_data.line,
|
||||
self.url_data.column)
|
||||
elif key == 1:
|
||||
return self.url_data.url
|
||||
elif key == 2:
|
||||
return self.url_data.name
|
||||
elif key == 3:
|
||||
return (self.url_data.valid, self.url_data.result)
|
||||
raise IndexError("invalid index %d" % key)
|
||||
|
||||
def init_display (self):
|
||||
"""Store formatted display texts from URL data."""
|
||||
# result
|
||||
if self.url_data.valid:
|
||||
if self.url_data.warnings:
|
||||
self.result_color = QtCore.Qt.darkYellow
|
||||
text = u"\n".join(x[1] for x in self.url_data.warnings)
|
||||
result = u"Warning: %s" % strformat.limit(text, length=25)
|
||||
else:
|
||||
self.result_color = QtCore.Qt.darkGreen
|
||||
result = u"Valid"
|
||||
if self.url_data.result:
|
||||
result += u": %s" % self.url_data.result
|
||||
else:
|
||||
self.result_color = QtCore.Qt.darkRed
|
||||
result = u"Error"
|
||||
if self.url_data.result:
|
||||
result += u": %s" % self.url_data.result
|
||||
# Parent URL
|
||||
if self.url_data.parent_url:
|
||||
parent = u"%s%s%s" % (self.url_data.parent_url,
|
||||
(_(", line %d") % self.url_data.line),
|
||||
(_(", col %d") % self.url_data.column))
|
||||
else:
|
||||
parent = u""
|
||||
# display values
|
||||
self.display = [
|
||||
# Parent URL
|
||||
parent,
|
||||
# URL
|
||||
unicode(self.url_data.url),
|
||||
# Name
|
||||
self.url_data.name,
|
||||
# Result
|
||||
result,
|
||||
]
|
||||
|
||||
def init_tooltips (self):
|
||||
"""Store formatted tooltip texts from URL data."""
|
||||
# Display warnings in result tooltip
|
||||
if self.url_data.warnings:
|
||||
text = u"\n".join(x[1] for x in self.url_data.warnings)
|
||||
result = strformat.wrap(text, 60)
|
||||
else:
|
||||
result = u""
|
||||
self.tooltips = [
|
||||
# Parent URL
|
||||
u"",
|
||||
# URL
|
||||
unicode(self.url_data.url),
|
||||
# Name
|
||||
self.url_data.name,
|
||||
# Result
|
||||
result,
|
||||
]
|
||||
|
||||
|
||||
class UrlItemModel(QtCore.QAbstractItemModel):
|
||||
"""Model class for list of URL items."""
|
||||
|
||||
def __init__ (self, parent=None):
|
||||
"""Set empty URL item list."""
|
||||
super(UrlItemModel, self).__init__(parent)
|
||||
# list of UrlItem objects
|
||||
self.urls = []
|
||||
|
||||
def rowCount (self, parent=QtCore.QModelIndex()):
|
||||
"""Return number of URL items."""
|
||||
return len(self.urls)
|
||||
|
||||
def columnCount (self, parent=QtCore.QModelIndex()):
|
||||
"""Return number of header columns."""
|
||||
return len(Headers)
|
||||
|
||||
def parent (self, child=QtCore.QModelIndex()):
|
||||
"""Return empty QModelIndex since the URL list is not hierarchical."""
|
||||
return QtCore.QModelIndex()
|
||||
|
||||
def index (self, row, column, parent=QtCore.QModelIndex()):
|
||||
"""Return index of URL item in given row and column."""
|
||||
return self.createIndex(row, column)
|
||||
|
||||
def data (self, index, role=QtCore.Qt.DisplayRole):
|
||||
"""Return URL item data at given index for given role."""
|
||||
V = QtCore.QVariant
|
||||
if not index.isValid() or \
|
||||
not (0 <= index.row() < len(self.urls)):
|
||||
return EmptyQVariant
|
||||
urlitem = self.urls[index.row()]
|
||||
column = index.column()
|
||||
if role == QtCore.Qt.DisplayRole:
|
||||
return V(urlitem.display[column])
|
||||
elif role == QtCore.Qt.ToolTipRole:
|
||||
return V(urlitem.tooltips[column])
|
||||
elif role == QtCore.Qt.TextColorRole and column == 3:
|
||||
return QtGui.QColor(urlitem.result_color)
|
||||
else:
|
||||
return EmptyQVariant
|
||||
|
||||
def headerData (self, section, orientation, role):
|
||||
"""Return header column data for given parameters."""
|
||||
if orientation == QtCore.Qt.Horizontal and \
|
||||
role == QtCore.Qt.DisplayRole:
|
||||
return Headers[section]
|
||||
return EmptyQVariant
|
||||
|
||||
def flags (self, index):
|
||||
"""Return flags that given valid item index is enabled and
|
||||
selected."""
|
||||
if not index.isValid():
|
||||
return 0
|
||||
return QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsSelectable
|
||||
|
||||
def clear (self):
|
||||
"""Empty the URL item list."""
|
||||
self.beginResetModel()
|
||||
self.urls = []
|
||||
self.endResetModel()
|
||||
|
||||
def log_url (self, url_data):
|
||||
"""Add URL data to tree model."""
|
||||
row = self.rowCount()
|
||||
self.beginInsertRows(QtCore.QModelIndex(), row, row)
|
||||
self.urls.append(UrlItem(url_data))
|
||||
self.endInsertRows()
|
||||
return True
|
||||
|
||||
def getUrlItem (self, index):
|
||||
"""Get URL item object at given index."""
|
||||
if not index.isValid() or \
|
||||
not (0 <= index.row() < len(self.urls)):
|
||||
return None
|
||||
return self.urls[index.row()]
|
||||
|
||||
def sort (self, column, order=QtCore.Qt.AscendingOrder):
|
||||
"""Sort URL items by given column and order."""
|
||||
self.layoutAboutToBeChanged.emit()
|
||||
reverse = (order == QtCore.Qt.DescendingOrder)
|
||||
self.urls.sort(key=operator.itemgetter(column), reverse=reverse)
|
||||
self.layoutChanged.emit()
|
||||
|
|
@ -1,87 +0,0 @@
|
|||
# -*- coding: iso-8859-1 -*-
|
||||
# Copyright (C) 2010-2014 Bastian Kleineidam
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along
|
||||
# with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
from PyQt4 import QtGui, QtCore
|
||||
|
||||
FilterHtml = _("HTML output (*.html)")
|
||||
FilterText = _("Text output (*.txt)")
|
||||
FilterXml = _("XML output (*.xml)")
|
||||
FilterCsv = _("CSV output (*.csv)")
|
||||
|
||||
LoggerFilters = (
|
||||
FilterHtml,
|
||||
FilterText,
|
||||
FilterXml,
|
||||
FilterCsv,
|
||||
)
|
||||
|
||||
Logtype2Filter = {
|
||||
'html': FilterHtml,
|
||||
'text': FilterText,
|
||||
'xml': FilterXml,
|
||||
'csv': FilterCsv,
|
||||
}
|
||||
Filter2Logtype = {v: k for k, v in Logtype2Filter.items()}
|
||||
|
||||
Logtype2FileExt = {
|
||||
"html": ".html",
|
||||
"text": ".txt",
|
||||
"xml": ".xml",
|
||||
"csv": ".csv",
|
||||
}
|
||||
|
||||
def urlsave (parent, config, urls):
|
||||
"""Save URL results in file."""
|
||||
filename, logtype = get_save_filename(parent)
|
||||
if not filename:
|
||||
# user canceled
|
||||
return
|
||||
filename = unicode(filename)
|
||||
kwargs = dict(fileoutput=1, filename=filename, encoding="utf_8_sig")
|
||||
logger = config.logger_new(logtype, **kwargs)
|
||||
logger.start_output()
|
||||
for urlitem in urls:
|
||||
do_print = True
|
||||
logger.log_filter_url(urlitem.url_data, do_print)
|
||||
# inject the saved statistics before printing them
|
||||
logger.stats = config['logger'].stats
|
||||
logger.end_output()
|
||||
return logtype
|
||||
|
||||
|
||||
def get_save_filename (parent):
|
||||
"""Open file save dialog for given parent window and base directory.
|
||||
Return dialog result."""
|
||||
title = _("Save check results")
|
||||
func = QtGui.QFileDialog.getSaveFileName
|
||||
logtype = parent.saveresultas if parent.saveresultas else 'html'
|
||||
filters = ";;".join(sortwithfirst(LoggerFilters, Logtype2Filter[logtype]))
|
||||
filename = "linkchecker-out" + Logtype2FileExt[logtype]
|
||||
selectedFilter = QtCore.QString()
|
||||
res = func(parent, title, filename, filters, selectedFilter)
|
||||
logtype = Filter2Logtype.get(unicode(selectedFilter))
|
||||
return res, logtype
|
||||
|
||||
|
||||
def sortwithfirst(sequence, firstelement):
|
||||
"""Move firstelement in a sequence to the first position."""
|
||||
res = []
|
||||
for elem in sequence:
|
||||
if elem == firstelement:
|
||||
res.insert(0, elem)
|
||||
else:
|
||||
res.append(elem)
|
||||
return res
|
||||
|
|
@ -1,43 +0,0 @@
|
|||
# -*- coding: iso-8859-1 -*-
|
||||
# Copyright (C) 2011-2014 Bastian Kleineidam
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along
|
||||
# with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
"""Provide custom validators."""
|
||||
|
||||
from PyQt4 import QtGui
|
||||
import re
|
||||
|
||||
|
||||
def check_regex (value):
|
||||
"""Check if given string value can be compiled with re.compile()."""
|
||||
try:
|
||||
re.compile(value)
|
||||
except re.error:
|
||||
return False
|
||||
else:
|
||||
return True
|
||||
|
||||
|
||||
class PyRegexValidator (QtGui.QValidator):
|
||||
"""Validate input that it is a valid Python regular expression."""
|
||||
|
||||
def validate (self, input, pos):
|
||||
if check_regex(unicode(input)):
|
||||
return (QtGui.QValidator.Acceptable, pos)
|
||||
return (QtGui.QValidator.Intermediate, pos)
|
||||
|
||||
def fixup (self, input):
|
||||
while not check_regex(unicode(input)):
|
||||
input.chop(1)
|
||||
|
|
@ -26,14 +26,12 @@ LOG_ROOT = "linkcheck"
|
|||
LOG_CMDLINE = "linkcheck.cmdline"
|
||||
LOG_CHECK = "linkcheck.check"
|
||||
LOG_CACHE = "linkcheck.cache"
|
||||
LOG_GUI = "linkcheck.gui"
|
||||
LOG_THREAD = "linkcheck.thread"
|
||||
LOG_PLUGIN = "linkcheck.plugin"
|
||||
lognames = {
|
||||
"cmdline": LOG_CMDLINE,
|
||||
"checking": LOG_CHECK,
|
||||
"cache": LOG_CACHE,
|
||||
"gui": LOG_GUI,
|
||||
"thread": LOG_THREAD,
|
||||
"plugin": LOG_PLUGIN,
|
||||
"all": LOG_ROOT,
|
||||
|
|
|
|||
|
|
@ -1,78 +0,0 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- coding: iso-8859-1 -*-
|
||||
# Copyright (C) 2008-2014 Bastian Kleineidam
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along
|
||||
# with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
"""
|
||||
Check HTML pages for broken links. This is the GUI client.
|
||||
"""
|
||||
import sys
|
||||
import signal
|
||||
from linkcheck import configuration, drop_privileges, i18n
|
||||
from linkcheck.loader import is_frozen
|
||||
if is_frozen():
|
||||
# Let Python find the C++ runtime DLLs for PyQt.
|
||||
import os
|
||||
from linkcheck import get_install_data
|
||||
sys.path.append(os.path.join(get_install_data(), 'Microsoft.VC90.CRT'))
|
||||
from PyQt4.QtGui import QApplication
|
||||
from linkcheck.fileutil import is_readable
|
||||
from linkcheck.gui import LinkCheckerMain, get_app_style
|
||||
from linkcheck.gui.projects import ProjectExt
|
||||
|
||||
|
||||
def excepthook (window, etype, evalue, tb):
|
||||
"""Catch unhandled exceptions."""
|
||||
from cStringIO import StringIO
|
||||
from linkcheck.director.console import internal_error
|
||||
out = i18n.get_encoded_writer(out=StringIO(), encoding="utf-8")
|
||||
internal_error(out=out, etype=etype, evalue=evalue, tb=tb)
|
||||
# signal main window to be thread-safe
|
||||
window.error_signal.emit(out.getvalue())
|
||||
|
||||
|
||||
def main (argv=None):
|
||||
"""Initialize the Qt application, handle commandline arguments
|
||||
and show the main window."""
|
||||
if argv is None:
|
||||
argv = sys.argv
|
||||
app = QApplication(argv)
|
||||
app.setApplicationName(configuration.AppName)
|
||||
app.setApplicationVersion(configuration.Version)
|
||||
app.setOrganizationName(configuration.Author)
|
||||
QApplication.setStyle(get_app_style())
|
||||
QApplication.setPalette(QApplication.style().standardPalette())
|
||||
args = app.arguments()
|
||||
mainkwargs = {}
|
||||
if len(args) > 1:
|
||||
fileorurl = unicode(args[1])
|
||||
if is_readable(fileorurl) and fileorurl.lower().endswith(ProjectExt):
|
||||
mainkwargs["project"] = fileorurl
|
||||
else:
|
||||
mainkwargs["url"] = fileorurl
|
||||
signal.signal(signal.SIGINT, signal.SIG_DFL)
|
||||
# use local variable here to avoid garbage collection of the main
|
||||
# window before app.exec_() finishes
|
||||
window = LinkCheckerMain(**mainkwargs)
|
||||
window.show()
|
||||
window.raise_() # this will raise the window on Mac OS X
|
||||
drop_privileges()
|
||||
sys.excepthook = \
|
||||
lambda etype, evalue, tb: excepthook(window, etype, evalue, tb)
|
||||
sys.exit(app.exec_())
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
|
@ -1,2 +0,0 @@
|
|||
[Paths]
|
||||
qt_plugpath=Plugins
|
||||
|
|
@ -2,7 +2,7 @@ XGETTEXT := xgettext
|
|||
MSGFMT := msgfmt
|
||||
MSGMERGE := msgmerge
|
||||
POSOURCES = $(shell find ../linkcheck -name \*.py) \
|
||||
../linkchecker ../linkchecker-gui /usr/lib/python2.7/argparse.py
|
||||
../linkchecker /usr/lib/python2.7/argparse.py
|
||||
LDIR = ../share/locale
|
||||
PACKAGE = linkchecker
|
||||
TEMPLATE = $(PACKAGE).pot
|
||||
|
|
|
|||