././@PaxHeader 0000000 0000000 0000000 00000000034 00000000000 010212 x ustar 00 28 mtime=1729164244.0723557
irclog2html-4.0.0/ 0000775 0001750 0001750 00000000000 14704171724 011602 5 ustar 00mg mg ././@PaxHeader 0000000 0000000 0000000 00000000026 00000000000 010213 x ustar 00 22 mtime=1666937894.0
irclog2html-4.0.0/.coveragerc 0000644 0001750 0001750 00000000431 14326672046 013722 0 ustar 00mg mg [run]
source = irclog2html
[paths]
source =
src/
.tox/*/lib/python*/site-packages/
.tox/pypy*/site-packages/
[report]
omit = */tests/*,*/xchatlogsplit.py
exclude_lines =
pragma: nocover
except ImportError:
except NameError:
if __name__ == .__main__.:
././@PaxHeader 0000000 0000000 0000000 00000000026 00000000000 010213 x ustar 00 22 mtime=1571767933.0
irclog2html-4.0.0/.gitignore 0000644 0001750 0001750 00000000371 13553643175 013576 0 ustar 00mg mg parts/
eggs/
develop-eggs/
irclog2html.egg-info/
bin/
.installed.cfg
testcases/*.log.html
testcases/index.html
testcases/irclog.css
dist/
tmp/
build/
temp/
distribute-0.6.10.tar.gz
.tox/
python/
*.pyc
__pycache__/
.coverage
coverage.xml
.coverage.*
././@PaxHeader 0000000 0000000 0000000 00000000026 00000000000 010213 x ustar 00 22 mtime=1729164085.0
irclog2html-4.0.0/CHANGES.rst 0000664 0001750 0001750 00000016355 14704171465 013420 0 ustar 00mg mg Changelog
=========
4.0.0 (2024-10-17)
------------------
- Remove CGI support if you're using Python 3.13 or newer. You'll have to
use the WSGI support instead.
- Add support for Python 3.12 and 3.13.
3.0.0 (2023-08-28)
------------------
- Drop support for Python 2.7 and 3.6.
- Add support for Python 3.10 and 3.11.
- Make permalinks permanent even from the latest.html file, by emitting the
filename in the links.
- Add to set initial scale to 1 for improved mobile
experience (`PR 32 `_).
- Support logs files created by `ii (Irc it) `_
(`PR 33 `_).
2.17.3 (2021-07-08)
-------------------
- Add support for Python 3.8 and 3.9.
- Drop support for Python 3.5.
- Fix a bug where specifying --output-dir (-o) to logs2html would mistakenly
skip generating some HTML files if they existed in the source directory
(`issue 29 `_).
2.17.2 (2019-04-23)
-------------------
- Drop support for Python 3.4.
2.17.1 (2018-11-25)
-------------------
- Add support for Python 3.7.
- Drop support for Python 3.3.
- Support ``python -m irclog2html`` as shortcut for
``python -m irclog2html.irclog2html``.
- Make irclogserver ignore hidden directories (such as .git).
2.17.0 (2018-02-21)
-------------------
- Support `ii `_ logs which use Unix
timestamps (https://github.com/mgedmin/irclog2html/pull/21).
Pull request by Cédric Krier.
2.16.0 (2017-12-20)
-------------------
- Support Python 3.6.
- Fix for duplicated lines with the same time where the resulting HTML ``id``
anchors would evolve into long form like "t22:24:49-2-3-4-5-6-7-8-9-10"
instead of "t22:24:49-10" resulting in significant output file size growth
in some cases.
- Add --output-dir (-o) parameter to logs2html so you can place the generated
HTML files in a directory different from the input directory (`PR #20
`_).
2.15.3 (2016-12-08)
-------------------
- In some circumstances parts of a message up to the last '>' could be lost
(https://github.com/mgedmin/irclog2html/issues/19).
2.15.2 (2016-10-07)
-------------------
- ``irclogserver`` channel list is now split into old channels and active
channels, detected by checking whether the directory modification date
is newer or older than 7 days.
- 2nd-level headings now have the same color as 1st-level headings.
- ``irclogserver`` no longer shows a 404 if you omit the trailing ``/``
after a channel name in the URL.
2.15.1 (2016-09-25)
-------------------
- Lines with the same timestamp now get different HTML anchors
(https://github.com/mgedmin/irclog2html/issues/17). Thanks
to Bryan Bishop for the original pull request.
2.15.0 (2016-09-25)
-------------------
- There's a new ``irclogserver`` script that can be used to serve
dynamically-generated IRC logs and perform search. It can also be
deployed via WSGI. Portions contributed by Albertas Agejevas
(https://github.com/mgedmin/irclog2html/pull/9).
- Index pages group the logs by month
(https://github.com/mgedmin/irclog2html/issues/12).
- Drop support for Python 2.6.
2.14.0 (2014-12-12)
-------------------
- Add -o option to specify the output file name. Patch by Moises Silva
(https://github.com/mgedmin/irclog2html/pull/7).
2.13.1 (2014-02-01)
-------------------
- Add support for Windows (e.g. refrain from creating latest.log.html
symlinks).
2.13.0 (2013-12-18)
-------------------
- Handle gzipped files transparently
(https://github.com/mgedmin/irclog2html/issues/5).
2.12.1 (2013-03-22)
-------------------
* Fix AttributeError in irclogsearch on Python 2.7
(https://github.com/mgedmin/irclog2html/issues/1).
2.12.0 (2013-03-18)
-------------------
* Moved to Github.
* Add support for Python 3.3.
* Drop support for Python 2.4 and 2.5.
* Fix URL linkifier to not include trailing punctuation (LP#1155906).
2.11.1 (2013-03-17)
-------------------
* logs2html also accepts filenames that contain YYYYMMDD dates (in addition to
YYYY-MM-DD). Patch by Holger Just. Fixes LP#1031642.
2.11.0 (2012-07-30)
-------------------
* irclogsearch can be told about the filename pattern of log files via an
environment variable (IRCLOG_GLOB). Patch by Jonathan Kinred.
2.10.0 (2012-02-12)
-------------------
* New option: --glob-pattern. Patch by Albertas Agejevas.
Fixes LP#912310.
* Links in logs are marked with rel="nofollow". Patch by Matt Wheeler.
Fixes LP#914553.
* New option: --version.
* New option: -c, --config=FILE.
2.9.2 (2011-01-16)
------------------
* Support XChat Latin/Unicode hybrid encoding (http://xchat.org/encoding/).
Fixes LP#703622.
* irclog2html copies irclog.css file into the destination directory.
Fixes LP#608727.
2.9.1 (2010-08-06)
------------------
* Make sure irclog.css is installed in the right place; logs2html needs it.
2.9 (2010-08-06)
----------------
* Restructured source tree, made irclogs2html into a package, added setup.py,
buildout.cfg, bootstrap.py, Makefile, HACKING.txt; moved old porting test
suite into a subdirectory (porting).
* logs2html copies irclog.css file into the destination directory.
* Released into PyPI.
2.8 (2010-07-22)
----------------
* Added README.txt and CHANGES.txt.
* Support dircproxy log files (new date format: "[15 Jan 08:42]",
strip ident and IP address from nicknames). Patch by Paul Frields.
* New option: --dircproxy also makes irclog2html strip a single leading
'+' or '-' from messages.
2.7.1 (2009-04-30)
------------------
* Bug in logs2html.py error reporting, reported by Ondrej Baudys.
2.7 (2008-06-10)
----------------
* New style: mediawiki. Patch by Ian Weller.
2.6 (2007-10-30)
----------------
* Support another date format (Oct 17 10:53:26). Patch by Matthew Barnes.
2.5.1 (2007-03-22)
------------------
* logs2html.py: add a stable link to the latest log file
(suggested by Chris Foster).
2.5 (2007-01-22)
----------------
* New option: --searchbox.
* Search CGI script improvements (e.g. put newest matches on top).
2.4 (2006-12-11)
----------------
* Added a sample CGI script for brute-force log searches.
2.3 (2005-03-08)
----------------
* Use xhtmltable style by default.
* Added a copy of the navbar at the bottom.
2.2 (2005-02-04)
----------------
* Support supybot's ChannelLogger date format (e.g. 02-Feb-2004).
* Fixed broken timestamp hyperlinks in xhtml/xhtmltable styles.
* CSS tweaks.
2.1mg (2005-01-09)
------------------
* Ported irclog2html.pl version 2.1 by Jeff Waugh from Perl to Python.
* New styles: xhtml, xhtmltable.
* New options: --title, --{prev,index,next}-{url,title}
* Removed hardcoded nick colour preferences for jdub, cantaker and chuckd
* Bugfix: colours are preserver accross nick changes (irclog2html.pl tried to
do that, but had a bug in a regex)
* Added ISO8601 timestamp support (e.g. 2005-01-09T12:43:11).
* More careful URL linkification (stop at ', ", ), >).
* Added logs2html.py script for mass-conversion of logs.
* Added support for xchat log files.
* Added xchatlogsplit.py script for splitting xchat logs on day boundaries so they're suitable as input for logs2html.py.
././@PaxHeader 0000000 0000000 0000000 00000000026 00000000000 010213 x ustar 00 22 mtime=1560428581.0
irclog2html-4.0.0/COPYING 0000644 0001750 0001750 00000043152 13500440045 012624 0 ustar 00mg mg GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Lesser General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
{description}
Copyright (C) {year} {fullname}
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.
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
{signature of Ty Coon}, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License.
././@PaxHeader 0000000 0000000 0000000 00000000026 00000000000 010213 x ustar 00 22 mtime=1560428581.0
irclog2html-4.0.0/HACKING.rst 0000644 0001750 0001750 00000001313 13500440045 013360 0 ustar 00mg mg Developing irclog2html
======================
To play with the scripts without installing, use::
make
bin/irclog2html --help
bin/logs2html --help
To run the test suite, use::
make test
or (even better) ::
detox
The testcases directory contains some sample logs, so you can try ::
bin/logs2html testcases
and look at testcases/index.html afterwards.
To play with the CGI script, try ::
IRCLOG_LOCATION=testcases bin/irclogsearch q=query
But I don't have make!
======================
Don't worry, feel free to use buildout directly::
virtualenv python
python/bin/python bootstrap.py
bin/buildout
bin/test
bin/irclog2html --help
bin/logs2html --help
././@PaxHeader 0000000 0000000 0000000 00000000026 00000000000 010213 x ustar 00 22 mtime=1560428581.0
irclog2html-4.0.0/MANIFEST.in 0000644 0001750 0001750 00000000752 13500440045 013326 0 ustar 00mg mg include bootstrap.py
include buildout.cfg
include *.rst
include tox.ini
include Makefile
include src/irclog2html/irclog.css
include src/irclog2html/tests/*.py
include src/irclog2html/tests/*.cfg
include src/irclog2html/tests/*.log
include porting/*.txt
include porting/*.py
include porting/*.pl
include porting/testcases/*.log
include testcases/*.log
include .gitignore
include .travis.yml
include appveyor.yml
include .coveragerc
include COPYING
# added by check_manifest.py
include *.mk
././@PaxHeader 0000000 0000000 0000000 00000000026 00000000000 010213 x ustar 00 22 mtime=1729090216.0
irclog2html-4.0.0/Makefile 0000664 0001750 0001750 00000003607 14703751250 013245 0 ustar 00mg mg PYTHON = python3
scripts = bin/test bin/irclog2html bin/logs2html bin/irclogsearch bin/irclogserver
.PHONY: all
all: $(scripts) ##: build a local buildout with all the scripts
.PHONY: test
test: ##: run tests
tox -p auto
.PHONY: flake8
flake8: ##: check for style problems
tox -e flake8
.PHONY: coverage
coverage: ##: measure test coverage
tox -e coverage
.PHONY: diff-cover
diff-cover: ##: find untested code on this branch
tox -e coverage
coverage xml
diff-cover coverage.xml
.PHONY: clean
clean: ##: clean up build artifacts
rm -f testcases/*.html testcases/*.css
.PHONY: releasechecklist
releasechecklist: check-date # also release.mk will add other checks
FILE_WITH_VERSION = src/irclog2html/_version.py
FILE_WITH_METADATA = src/irclog2html/_version.py
include release.mk
# override the release recipe in release.mk
define release_recipe =
$(default_release_recipe_publish_and_tag)
$(default_release_recipe_increment_and_push)
@echo "Then please create a GitHub release with"
@echo
@echo " gh release create"
@echo
endef
.PHONY: check-date
check-date:
@date_line="__date__ = '"`date +%Y-%m-%d`"'" && \
grep -q "^$$date_line$$" $(FILE_WITH_METADATA) || { \
echo "$(FILE_WITH_METADATA) doesn't specify $$date_line"; \
echo "Please run make update-date"; exit 1; }
.PHONY: update-date
update-date: ##: set release date in source code to today
sed -i -e "s/^__date__ = '.*'/__date__ = '"`date +%Y-%m-%d`"'/" $(FILE_WITH_METADATA)
python:
virtualenv -p $(PYTHON) python
python/bin/virtualenv:
python/bin/pip install -U setuptools virtualenv
bin/buildout: python bootstrap.py
python/bin/pip install -U setuptools
python/bin/python bootstrap.py
touch -c $@
$(scripts): bin/buildout buildout.cfg setup.py python/bin/virtualenv
bin/buildout
touch -c $(scripts)
././@PaxHeader 0000000 0000000 0000000 00000000034 00000000000 010212 x ustar 00 28 mtime=1729164244.0723557
irclog2html-4.0.0/PKG-INFO 0000644 0001750 0001750 00000032363 14704171724 012704 0 ustar 00mg mg Metadata-Version: 2.1
Name: irclog2html
Version: 4.0.0
Summary: Convert IRC logs to HTML
Home-page: https://mg.pov.lt/irclog2html/
Author: Marius Gedminas
Author-email: marius@gedmin.as
License: GPL v2 or v3
Keywords: irc log colorizer html wsgi
Platform: any
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: System Administrators
Classifier: License :: OSI Approved :: GNU General Public License v2 (GPLv2)
Classifier: License :: OSI Approved :: GNU General Public License v3 (GPLv3)
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3.7
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: Implementation :: CPython
Classifier: Programming Language :: Python :: Implementation :: PyPy
Requires-Python: >=3.7
Description-Content-Type: text/x-rst
License-File: COPYING
Provides-Extra: test
Requires-Dist: zope.testing; extra == "test"
===========
irclog2html
===========
Converts IRC log files to HTML with pretty colours.
Quick start
===========
Installation::
pip install irclog2html
Quick usage for a single log file::
irclog2html --help
irclog2html filename.log (produces filename.log.html)
Mass-conversion of logs (one file per day, with YYYY-MM-DD in the filename)
with next/prev links, with mtime checks, usable from cron::
logs2html directory/ (looks for *.log and *.log.gz, produces *.log.html)
Configuration files
===================
Since you probably don't want to keep specifying the same options on the
command line every time you run logs2html, you can create a config file.
For example::
-t 'IRC logs for #mychannel'
-p 'IRC logs for #mychannel for '
# the following needs some extra Apache setup to enable the CGI/WSGI script
--searchbox
# where we keep the logs
/full/path/to/directory/
Use it like this::
logs2html -c /path/to/mychannel.conf
Lines starting with a ``#`` are ignored. Other lines are interpreted as
command-line options.
The order matters: options on the command line before the ``-c FILE`` will
be overriden by option in the config file. Options specified after ``-c FILE``
will override the options in the config file.
You can include more than one config file by repeating ``-c FILE``. You
can include config files from other config files. You can even create loops of
config files and then watch and laugh manically as logs2html sits there burning
your CPU.
CGI script for log searching
============================
.. warning::
The script can be easily abused to cause a denial of service attack; it
parses *all* log files every time you perform a search.
You can generate search boxes on IRC log pages by passing the ``--searchbox``
option to ``logs2html``. Here's an example Apache config snippet that makes
it work::
RewriteRule ^/my-irclog/search/$ /my-irclog/search [R,L]
ScriptAlias /my-irclog/search /usr/local/bin/irclogsearch
SetEnv IRCLOG_LOCATION "/var/www/my-irclog/"
# Uncomment the following if your log files use a different format
#SetEnv IRCLOG_GLOB "*.log.????-??-??"
# (this will also automatically handle *.log.????-??-??.gz)
WSGI script for log serving
===========================
.. warning::
The script can be easily abused to cause a denial of service attack; it
parses *all* log files every time you perform a search.
There's now an experimental WSGI script that can generate HTML for the
logs on the fly. You can use it if you don't like cron scripts and CGI.
Here's an example Apache config snippet::
WSGIScriptAlias /irclogs /usr/local/bin/irclogserver
SetEnv IRCLOG_LOCATION "/var/www/my-irclog/"
# Uncomment the following if your log files use a different format
#SetEnv IRCLOG_GLOB "*.log.????-??-??"
# (this will also automatically handle *.log.????-??-??.gz)
Currently it has certain downsides:
- configuration is very limited, e.g you cannot specify titles or styles
or enable dircproxy mode
- HTML files in the irc log directory will take precedence over
dynamically-generated logs even if they're older than the corresponding
log file (but on the plus side you can use that to have dynamic search
via WSGI, but keep statically-generated HTML files with your own config
tweaks)
WSGI script for multi-channel log serving
=========================================
.. warning::
The script can be easily abused to cause a denial of service attack; it
parses *all* log files every time you perform a search.
The experimental WSGI script can serve logs for multiple channels::
WSGIScriptAlias /irclogs /usr/local/bin/irclogserver
SetEnv IRCLOG_CHAN_DIR "/var/www/my-irclog/"
# Uncomment the following if your log files use a different format
#SetEnv IRCLOG_GLOB "*.log.????-??-??"
# (this will also automatically handle *.log.????-??-??.gz)
Now ``/irclogs`` will show a list of channels (subdirectories under
``/var/www/my-irclog/``), and ``/irclogs/channel/`` will show the
date index for that channel.
Misc
====
Website: https://mg.pov.lt/irclog2html/
Bug tracker:
https://github.com/mgedmin/irclog2html/issues
Licence: GPL v2 or v3 (https://www.gnu.org/copyleft/gpl.html)
|buildstatus|_ |appveyor|_ |coverage|_
.. |buildstatus| image:: https://github.com/mgedmin/irclog2html/workflows/build/badge.svg?branch=master
.. _buildstatus: https://github.com/mgedmin/irclog2html/actions
.. |appveyor| image:: https://ci.appveyor.com/api/projects/status/github/mgedmin/irclog2html?branch=master&svg=true
.. _appveyor: https://ci.appveyor.com/project/mgedmin/irclog2html
.. |coverage| image:: https://coveralls.io/repos/mgedmin/irclog2html/badge.svg?branch=master
.. _coverage: https://coveralls.io/r/mgedmin/irclog2html
Changelog
=========
4.0.0 (2024-10-17)
------------------
- Remove CGI support if you're using Python 3.13 or newer. You'll have to
use the WSGI support instead.
- Add support for Python 3.12 and 3.13.
3.0.0 (2023-08-28)
------------------
- Drop support for Python 2.7 and 3.6.
- Add support for Python 3.10 and 3.11.
- Make permalinks permanent even from the latest.html file, by emitting the
filename in the links.
- Add to set initial scale to 1 for improved mobile
experience (`PR 32 `_).
- Support logs files created by `ii (Irc it) `_
(`PR 33 `_).
2.17.3 (2021-07-08)
-------------------
- Add support for Python 3.8 and 3.9.
- Drop support for Python 3.5.
- Fix a bug where specifying --output-dir (-o) to logs2html would mistakenly
skip generating some HTML files if they existed in the source directory
(`issue 29 `_).
2.17.2 (2019-04-23)
-------------------
- Drop support for Python 3.4.
2.17.1 (2018-11-25)
-------------------
- Add support for Python 3.7.
- Drop support for Python 3.3.
- Support ``python -m irclog2html`` as shortcut for
``python -m irclog2html.irclog2html``.
- Make irclogserver ignore hidden directories (such as .git).
2.17.0 (2018-02-21)
-------------------
- Support `ii `_ logs which use Unix
timestamps (https://github.com/mgedmin/irclog2html/pull/21).
Pull request by Cédric Krier.
2.16.0 (2017-12-20)
-------------------
- Support Python 3.6.
- Fix for duplicated lines with the same time where the resulting HTML ``id``
anchors would evolve into long form like "t22:24:49-2-3-4-5-6-7-8-9-10"
instead of "t22:24:49-10" resulting in significant output file size growth
in some cases.
- Add --output-dir (-o) parameter to logs2html so you can place the generated
HTML files in a directory different from the input directory (`PR #20
`_).
2.15.3 (2016-12-08)
-------------------
- In some circumstances parts of a message up to the last '>' could be lost
(https://github.com/mgedmin/irclog2html/issues/19).
2.15.2 (2016-10-07)
-------------------
- ``irclogserver`` channel list is now split into old channels and active
channels, detected by checking whether the directory modification date
is newer or older than 7 days.
- 2nd-level headings now have the same color as 1st-level headings.
- ``irclogserver`` no longer shows a 404 if you omit the trailing ``/``
after a channel name in the URL.
2.15.1 (2016-09-25)
-------------------
- Lines with the same timestamp now get different HTML anchors
(https://github.com/mgedmin/irclog2html/issues/17). Thanks
to Bryan Bishop for the original pull request.
2.15.0 (2016-09-25)
-------------------
- There's a new ``irclogserver`` script that can be used to serve
dynamically-generated IRC logs and perform search. It can also be
deployed via WSGI. Portions contributed by Albertas Agejevas
(https://github.com/mgedmin/irclog2html/pull/9).
- Index pages group the logs by month
(https://github.com/mgedmin/irclog2html/issues/12).
- Drop support for Python 2.6.
2.14.0 (2014-12-12)
-------------------
- Add -o option to specify the output file name. Patch by Moises Silva
(https://github.com/mgedmin/irclog2html/pull/7).
2.13.1 (2014-02-01)
-------------------
- Add support for Windows (e.g. refrain from creating latest.log.html
symlinks).
2.13.0 (2013-12-18)
-------------------
- Handle gzipped files transparently
(https://github.com/mgedmin/irclog2html/issues/5).
2.12.1 (2013-03-22)
-------------------
* Fix AttributeError in irclogsearch on Python 2.7
(https://github.com/mgedmin/irclog2html/issues/1).
2.12.0 (2013-03-18)
-------------------
* Moved to Github.
* Add support for Python 3.3.
* Drop support for Python 2.4 and 2.5.
* Fix URL linkifier to not include trailing punctuation (LP#1155906).
2.11.1 (2013-03-17)
-------------------
* logs2html also accepts filenames that contain YYYYMMDD dates (in addition to
YYYY-MM-DD). Patch by Holger Just. Fixes LP#1031642.
2.11.0 (2012-07-30)
-------------------
* irclogsearch can be told about the filename pattern of log files via an
environment variable (IRCLOG_GLOB). Patch by Jonathan Kinred.
2.10.0 (2012-02-12)
-------------------
* New option: --glob-pattern. Patch by Albertas Agejevas.
Fixes LP#912310.
* Links in logs are marked with rel="nofollow". Patch by Matt Wheeler.
Fixes LP#914553.
* New option: --version.
* New option: -c, --config=FILE.
2.9.2 (2011-01-16)
------------------
* Support XChat Latin/Unicode hybrid encoding (http://xchat.org/encoding/).
Fixes LP#703622.
* irclog2html copies irclog.css file into the destination directory.
Fixes LP#608727.
2.9.1 (2010-08-06)
------------------
* Make sure irclog.css is installed in the right place; logs2html needs it.
2.9 (2010-08-06)
----------------
* Restructured source tree, made irclogs2html into a package, added setup.py,
buildout.cfg, bootstrap.py, Makefile, HACKING.txt; moved old porting test
suite into a subdirectory (porting).
* logs2html copies irclog.css file into the destination directory.
* Released into PyPI.
2.8 (2010-07-22)
----------------
* Added README.txt and CHANGES.txt.
* Support dircproxy log files (new date format: "[15 Jan 08:42]",
strip ident and IP address from nicknames). Patch by Paul Frields.
* New option: --dircproxy also makes irclog2html strip a single leading
'+' or '-' from messages.
2.7.1 (2009-04-30)
------------------
* Bug in logs2html.py error reporting, reported by Ondrej Baudys.
2.7 (2008-06-10)
----------------
* New style: mediawiki. Patch by Ian Weller.
2.6 (2007-10-30)
----------------
* Support another date format (Oct 17 10:53:26). Patch by Matthew Barnes.
2.5.1 (2007-03-22)
------------------
* logs2html.py: add a stable link to the latest log file
(suggested by Chris Foster).
2.5 (2007-01-22)
----------------
* New option: --searchbox.
* Search CGI script improvements (e.g. put newest matches on top).
2.4 (2006-12-11)
----------------
* Added a sample CGI script for brute-force log searches.
2.3 (2005-03-08)
----------------
* Use xhtmltable style by default.
* Added a copy of the navbar at the bottom.
2.2 (2005-02-04)
----------------
* Support supybot's ChannelLogger date format (e.g. 02-Feb-2004).
* Fixed broken timestamp hyperlinks in xhtml/xhtmltable styles.
* CSS tweaks.
2.1mg (2005-01-09)
------------------
* Ported irclog2html.pl version 2.1 by Jeff Waugh from Perl to Python.
* New styles: xhtml, xhtmltable.
* New options: --title, --{prev,index,next}-{url,title}
* Removed hardcoded nick colour preferences for jdub, cantaker and chuckd
* Bugfix: colours are preserver accross nick changes (irclog2html.pl tried to
do that, but had a bug in a regex)
* Added ISO8601 timestamp support (e.g. 2005-01-09T12:43:11).
* More careful URL linkification (stop at ', ", ), >).
* Added logs2html.py script for mass-conversion of logs.
* Added support for xchat log files.
* Added xchatlogsplit.py script for splitting xchat logs on day boundaries so they're suitable as input for logs2html.py.
././@PaxHeader 0000000 0000000 0000000 00000000026 00000000000 010213 x ustar 00 22 mtime=1618479352.0
irclog2html-4.0.0/README.rst 0000664 0001750 0001750 00000011521 14036004370 013257 0 ustar 00mg mg ===========
irclog2html
===========
Converts IRC log files to HTML with pretty colours.
Quick start
===========
Installation::
pip install irclog2html
Quick usage for a single log file::
irclog2html --help
irclog2html filename.log (produces filename.log.html)
Mass-conversion of logs (one file per day, with YYYY-MM-DD in the filename)
with next/prev links, with mtime checks, usable from cron::
logs2html directory/ (looks for *.log and *.log.gz, produces *.log.html)
Configuration files
===================
Since you probably don't want to keep specifying the same options on the
command line every time you run logs2html, you can create a config file.
For example::
-t 'IRC logs for #mychannel'
-p 'IRC logs for #mychannel for '
# the following needs some extra Apache setup to enable the CGI/WSGI script
--searchbox
# where we keep the logs
/full/path/to/directory/
Use it like this::
logs2html -c /path/to/mychannel.conf
Lines starting with a ``#`` are ignored. Other lines are interpreted as
command-line options.
The order matters: options on the command line before the ``-c FILE`` will
be overriden by option in the config file. Options specified after ``-c FILE``
will override the options in the config file.
You can include more than one config file by repeating ``-c FILE``. You
can include config files from other config files. You can even create loops of
config files and then watch and laugh manically as logs2html sits there burning
your CPU.
CGI script for log searching
============================
.. warning::
The script can be easily abused to cause a denial of service attack; it
parses *all* log files every time you perform a search.
You can generate search boxes on IRC log pages by passing the ``--searchbox``
option to ``logs2html``. Here's an example Apache config snippet that makes
it work::
RewriteRule ^/my-irclog/search/$ /my-irclog/search [R,L]
ScriptAlias /my-irclog/search /usr/local/bin/irclogsearch
SetEnv IRCLOG_LOCATION "/var/www/my-irclog/"
# Uncomment the following if your log files use a different format
#SetEnv IRCLOG_GLOB "*.log.????-??-??"
# (this will also automatically handle *.log.????-??-??.gz)
WSGI script for log serving
===========================
.. warning::
The script can be easily abused to cause a denial of service attack; it
parses *all* log files every time you perform a search.
There's now an experimental WSGI script that can generate HTML for the
logs on the fly. You can use it if you don't like cron scripts and CGI.
Here's an example Apache config snippet::
WSGIScriptAlias /irclogs /usr/local/bin/irclogserver
SetEnv IRCLOG_LOCATION "/var/www/my-irclog/"
# Uncomment the following if your log files use a different format
#SetEnv IRCLOG_GLOB "*.log.????-??-??"
# (this will also automatically handle *.log.????-??-??.gz)
Currently it has certain downsides:
- configuration is very limited, e.g you cannot specify titles or styles
or enable dircproxy mode
- HTML files in the irc log directory will take precedence over
dynamically-generated logs even if they're older than the corresponding
log file (but on the plus side you can use that to have dynamic search
via WSGI, but keep statically-generated HTML files with your own config
tweaks)
WSGI script for multi-channel log serving
=========================================
.. warning::
The script can be easily abused to cause a denial of service attack; it
parses *all* log files every time you perform a search.
The experimental WSGI script can serve logs for multiple channels::
WSGIScriptAlias /irclogs /usr/local/bin/irclogserver
SetEnv IRCLOG_CHAN_DIR "/var/www/my-irclog/"
# Uncomment the following if your log files use a different format
#SetEnv IRCLOG_GLOB "*.log.????-??-??"
# (this will also automatically handle *.log.????-??-??.gz)
Now ``/irclogs`` will show a list of channels (subdirectories under
``/var/www/my-irclog/``), and ``/irclogs/channel/`` will show the
date index for that channel.
Misc
====
Website: https://mg.pov.lt/irclog2html/
Bug tracker:
https://github.com/mgedmin/irclog2html/issues
Licence: GPL v2 or v3 (https://www.gnu.org/copyleft/gpl.html)
|buildstatus|_ |appveyor|_ |coverage|_
.. |buildstatus| image:: https://github.com/mgedmin/irclog2html/workflows/build/badge.svg?branch=master
.. _buildstatus: https://github.com/mgedmin/irclog2html/actions
.. |appveyor| image:: https://ci.appveyor.com/api/projects/status/github/mgedmin/irclog2html?branch=master&svg=true
.. _appveyor: https://ci.appveyor.com/project/mgedmin/irclog2html
.. |coverage| image:: https://coveralls.io/repos/mgedmin/irclog2html/badge.svg?branch=master
.. _coverage: https://coveralls.io/r/mgedmin/irclog2html
././@PaxHeader 0000000 0000000 0000000 00000000026 00000000000 010213 x ustar 00 22 mtime=1729083586.0
irclog2html-4.0.0/appveyor.yml 0000664 0001750 0001750 00000001605 14703734302 014170 0 ustar 00mg mg version: build-{build}-{branch}
environment:
matrix:
# https://www.appveyor.com/docs/installed-software#python lists available
# versions
- PYTHON: "C:\\Python37"
- PYTHON: "C:\\Python38"
- PYTHON: "C:\\Python39"
- PYTHON: "C:\\Python310"
- PYTHON: "C:\\Python311"
- PYTHON: "C:\\Python312"
- PYTHON: "C:\\Python313"
init:
- "echo %PYTHON%"
install:
- ps: |
if (-not (Test-Path $env:PYTHON)) {
curl -o install_python.ps1 https://raw.githubusercontent.com/matthew-brett/multibuild/11a389d78892cf90addac8f69433d5e22bfa422a/install_python.ps1
.\install_python.ps1
}
- ps: if (-not (Test-Path $env:PYTHON)) { throw "No $env:PYTHON" }
- "set PATH=%PYTHON%;%PYTHON%\\Scripts;%PATH%"
- python --version
- pip install -U virtualenv # upgrade pip in tox's virtualenvs
- pip install tox
build: off
test_script:
- tox -e py
././@PaxHeader 0000000 0000000 0000000 00000000026 00000000000 010213 x ustar 00 22 mtime=1714731170.0
irclog2html-4.0.0/bootstrap.py 0000664 0001750 0001750 00000016447 14615134242 014200 0 ustar 00mg mg ##############################################################################
#
# Copyright (c) 2006 Zope Foundation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
"""Bootstrap a buildout-based project
Simply run this script in a directory containing a buildout.cfg.
The script accepts buildout command-line options, so you can
use the -c option to specify an alternate configuration file.
"""
import os
import shutil
import sys
import tempfile
from optparse import OptionParser
__version__ = '2015-07-01'
# See zc.buildout's changelog if this version is up to date.
tmpeggs = tempfile.mkdtemp(prefix='bootstrap-')
usage = '''\
[DESIRED PYTHON FOR BUILDOUT] bootstrap.py [options]
Bootstraps a buildout-based project.
Simply run this script in a directory containing a buildout.cfg, using the
Python that you want bin/buildout to use.
Note that by using --find-links to point to local resources, you can keep
this script from going over the network.
'''
parser = OptionParser(usage=usage)
parser.add_option("--version",
action="store_true", default=False,
help=("Return bootstrap.py version."))
parser.add_option("-t", "--accept-buildout-test-releases",
dest='accept_buildout_test_releases',
action="store_true", default=False,
help=("Normally, if you do not specify a --version, the "
"bootstrap script and buildout gets the newest "
"*final* versions of zc.buildout and its recipes and "
"extensions for you. If you use this flag, "
"bootstrap and buildout will get the newest releases "
"even if they are alphas or betas."))
parser.add_option("-c", "--config-file",
help=("Specify the path to the buildout configuration "
"file to be used."))
parser.add_option("-f", "--find-links",
help=("Specify a URL to search for buildout releases"))
parser.add_option("--allow-site-packages",
action="store_true", default=False,
help=("Let bootstrap.py use existing site packages"))
parser.add_option("--buildout-version",
help="Use a specific zc.buildout version")
parser.add_option("--setuptools-version",
help="Use a specific setuptools version")
parser.add_option("--setuptools-to-dir",
help=("Allow for re-use of existing directory of "
"setuptools versions"))
options, args = parser.parse_args()
if options.version:
print("bootstrap.py version %s" % __version__)
sys.exit(0)
######################################################################
# load/install setuptools
try:
from urllib.request import urlopen
except ImportError:
from urllib2 import urlopen
ez = {}
if os.path.exists('ez_setup.py'):
exec(open('ez_setup.py').read(), ez)
else:
exec(urlopen('https://bootstrap.pypa.io/ez_setup.py').read(), ez)
if not options.allow_site_packages:
# ez_setup imports site, which adds site packages
# this will remove them from the path to ensure that incompatible versions
# of setuptools are not in the path
import site
# inside a virtualenv, there is no 'getsitepackages'.
# We can't remove these reliably
if hasattr(site, 'getsitepackages'):
for sitepackage_path in site.getsitepackages():
# Strip all site-packages directories from sys.path that
# are not sys.prefix; this is because on Windows
# sys.prefix is a site-package directory.
if sitepackage_path != sys.prefix:
sys.path[:] = [x for x in sys.path
if sitepackage_path not in x]
setup_args = dict(to_dir=tmpeggs, download_delay=0)
if options.setuptools_version is not None:
setup_args['version'] = options.setuptools_version
if options.setuptools_to_dir is not None:
setup_args['to_dir'] = options.setuptools_to_dir
ez['use_setuptools'](**setup_args)
import pkg_resources
import setuptools
# This does not (always?) update the default working set. We will
# do it.
for path in sys.path:
if path not in pkg_resources.working_set.entries:
pkg_resources.working_set.add_entry(path)
######################################################################
# Install buildout
ws = pkg_resources.working_set
setuptools_path = ws.find(
pkg_resources.Requirement.parse('setuptools')).location
# Fix sys.path here as easy_install.pth added before PYTHONPATH
cmd = [sys.executable, '-c',
'import sys; sys.path[0:0] = [%r]; ' % setuptools_path +
'from setuptools.command.easy_install import main; main()',
'-mZqNxd', tmpeggs]
find_links = os.environ.get(
'bootstrap-testing-find-links',
options.find_links or
('http://downloads.buildout.org/'
if options.accept_buildout_test_releases else None)
)
if find_links:
cmd.extend(['-f', find_links])
requirement = 'zc.buildout'
version = options.buildout_version
if version is None and not options.accept_buildout_test_releases:
# Figure out the most recent final version of zc.buildout.
import setuptools.package_index
_final_parts = '*final-', '*final'
def _final_version(parsed_version):
try:
return not parsed_version.is_prerelease
except AttributeError:
# Older setuptools
for part in parsed_version:
if (part[:1] == '*') and (part not in _final_parts):
return False
return True
index = setuptools.package_index.PackageIndex(
search_path=[setuptools_path])
if find_links:
index.add_find_links((find_links,))
req = pkg_resources.Requirement.parse(requirement)
if index.obtain(req) is not None:
best = []
bestv = None
for dist in index[req.project_name]:
distv = dist.parsed_version
if _final_version(distv):
if bestv is None or distv > bestv:
best = [dist]
bestv = distv
elif distv == bestv:
best.append(dist)
if best:
best.sort()
version = best[-1].version
if version:
requirement = '=='.join((requirement, version))
cmd.append(requirement)
import subprocess
if subprocess.call(cmd) != 0:
raise Exception(
"Failed to execute command:\n%s" % repr(cmd)[1:-1])
######################################################################
# Import and run buildout
ws.add_entry(tmpeggs)
ws.require(requirement)
import zc.buildout.buildout
if not [a for a in args if '=' not in a]:
args.append('bootstrap')
# if -c was provided, we push it back into args for buildout' main function
if options.config_file is not None:
args[0:0] = ['-c', options.config_file]
zc.buildout.buildout.main(args)
shutil.rmtree(tmpeggs)
././@PaxHeader 0000000 0000000 0000000 00000000026 00000000000 010213 x ustar 00 22 mtime=1560428581.0
irclog2html-4.0.0/buildout.cfg 0000644 0001750 0001750 00000000250 13500440045 014071 0 ustar 00mg mg [buildout]
develop = .
parts = irclog2html test
[irclog2html]
recipe = zc.recipe.egg
eggs = irclog2html
[test]
recipe = zc.recipe.testrunner
eggs = irclog2html[test]
././@PaxHeader 0000000 0000000 0000000 00000000034 00000000000 010212 x ustar 00 28 mtime=1729164244.0673554
irclog2html-4.0.0/porting/ 0000775 0001750 0001750 00000000000 14704171724 013264 5 ustar 00mg mg ././@PaxHeader 0000000 0000000 0000000 00000000026 00000000000 010213 x ustar 00 22 mtime=1560428581.0
irclog2html-4.0.0/porting/HISTORY.txt 0000644 0001750 0001750 00000000450 13500440045 015147 0 ustar 00mg mg Porting from Perl
=================
Originally irclog2html.py was a straight port of Jeff Waugh's irclog2html.pl.
This directory contains a test suite I used to make sure my port was producing
the same output as the original perl script.
To run the comparison tests, use::
python test.py
././@PaxHeader 0000000 0000000 0000000 00000000026 00000000000 010213 x ustar 00 22 mtime=1618479405.0
irclog2html-4.0.0/porting/irclog2html.pl 0000755 0001750 0001750 00000022345 14036004455 016050 0 ustar 00mg mg #!/usr/bin/perl
# irclog2html.pl Version 2.1mg - 27th July, 2001
# Copyright (C) 2000, Jeffrey W. Waugh
# Changed by Marius Gedminas (marius@pov.lt) on 2005-01-09:
# changed time regexps to support ISO-8601 (YYYY-MM-DDTHH:MM:SS) timestamps
# commented out print $time;
# fixed bugs in code that tried to preserve colours accross nick changes
# Author:
# Jeff Waugh
# Contributors:
# Rick Welykochy
# Alexander Else
# Released under the terms of the GNU GPL v2 or later
# http://www.gnu.org/copyleft/gpl.html
# Usage: irclog2html filename
# irclog2html will write out a colourised irc log, appending a .html
# extension to the output file.
####################################################################################
# Perl Configuration
use strict;
#$^W = 1; #RW# turn on warnings
my $VERSION = "2.1mg";
my $RELEASE = "27th July, 2001";
# Colouring stuff
my $a = 0.95; # tune these for the starting and ending concentrations of R,G,B
my $b = 0.5;
my $rgb = [ [$a,$b,$b], [$b,$a,$b], [$b,$b,$a], [$a,$a,$b], [$a,$b,$a], [$b,$a,$a] ];
my $rgbmax = 125; # tune these two for the outmost ranges of colour depth
my $rgbmin = 240;
####################################################################################
# Preferences
# Comment out the "table" assignment to use the plain version
my %prefs_colours = (
"part" => "#000099",
"join" => "#009900",
"server" => "#009900",
"nickchange" => "#009900",
"action" => "#CC00CC",
);
my %prefs_colour_nick = (
"jdub" => "#993333",
"cantanker" => "#006600",
"chuckd" => "#339999",
);
my %prefs_styles = (
"simplett" => "Text style with little use of colour",
"tt" => "Text style using colours for each nick",
"simpletable" => "Table style, without heavy use of colour",
"table" => "Default style, using a table with bold colours",
);
my $STYLE = "table";
####################################################################################
# Utility Functions & Variables
sub output_nicktext {
my ($nick, $text, $htmlcolour) = @_;
if ($STYLE eq "table") {
print OUTPUT "
\n";
} else {
print OUTPUT "$line \n";
}
}
sub html_rgb
{
my ($i,$ncolours) = @_;
$ncolours = 1 if $ncolours == 0;
my $n = $i % @$rgb;
my $m = $rgbmin + ($rgbmax - $rgbmin) * ($ncolours - $i) / $ncolours;
my $r = $rgb->[$n][0] * $m;
my $g = $rgb->[$n][1] * $m;
my $b = $rgb->[$n][2] * $m;
sprintf("#%02x%02x%02x",$r,$g,$b);
}
my $msg_usage = "Usage: irclog2html.pl [OPTION]... [FILE]
Colourises and converts IRC logs to HTML format for easy web reading.
-s, --style=[STYLE] format log according to specific style. style formats
described using irclog2html [-s|--style]
--colour-=[COLOUR] format output colour scheme. attributes
described using irclog2html [--colour]
Report bugs to Jeff Waugh .
";
my $msg_styles = "The following styles are available for use with irclog2html.pl:
simplett
Text style with little use of colour
tt
Text style using colours for each nick
simpletable
Table style, without heavy use of colour
table
Default style, using a table with bold colours
";
my $msg_colours = "The following attributes may be customized using the --colour
parameter:
join, part, action, server, nickchange
";
################################################################################
# Main
sub main {
my $inputfile;
my $nick;
my $time;
my $line;
my $text;
my $htmlcolour;
my $nickcount = 0;
my $NICKMAX = 30;
my %colours = %prefs_colours;
my %colour_nick = %prefs_colour_nick;
my %styles = %prefs_styles;
# Quit if there is no filename specified on the command line #
if ($#ARGV == -1) {
die "Required parameter missing\n\n$msg_usage";
}
# Loop through parameters, bringing filenames into $files #
my $count = 0;
while ($ARGV[$count]) {
if ($ARGV[$count] =~ /-s|--style.*/) {
$STYLE = $ARGV[$count];
if ($STYLE =~ /--style=.*/) {
$STYLE =~ s/--style=(.*)/$1/;
} else {
$count++;
$STYLE = $ARGV[$count];
}
if ($STYLE eq "") {
print $msg_styles;
return 0;
} elsif (!defined($styles{$STYLE})) {
die "irclog2html.pl: invalid style: `$STYLE'\n\n$msg_styles";
}
} elsif ($ARGV[$count] =~ /--colou?r.*/) {
my $colour_pref = $ARGV[$count];
my $colour = $colour_pref;
if ($colour_pref =~ /--colou?r$/) {
print $msg_colours;
return 0;
} else {
$colour_pref =~ s/--colou?r-(.*)?=.*/$1/;
$colour =~ s/--colou?r-.*?=(.*)/$1/;
$colours{$colour_pref} = $colour;
}
} else {
$inputfile = $ARGV[$count];
}
$count++;
}
# Open input and output files #
if (!$inputfile) {
# no file to open, print appropriate usage information
die "\n$msg_usage";
} elsif (!open(INPUT, $inputfile)) {
# not a vaild file to open, spew error and usage information
die "irclog2html.pl: cannot open $inputfile for reading\n\n$msg_usage";
}
if (!open(OUTPUT, ">$inputfile.html")) {
# can't open file for output, spew error
die "irclog2html.pl: cannot open $inputfile.html for writing\n";
}
# Begin output #
print OUTPUT qq{
$inputfile
};
if ($STYLE =~ /table/) {
print OUTPUT "
\n";
}
print OUTPUT qq{
Generated by irclog2html.pl $VERSION by Jeff Waugh
- find it at freshmeat.net!
};
close INPUT;
close OUTPUT;
return 0;
}
exit main;
././@PaxHeader 0000000 0000000 0000000 00000000026 00000000000 010213 x ustar 00 22 mtime=1729089975.0
irclog2html-4.0.0/porting/irclog2html.py 0000664 0001750 0001750 00000101627 14703750667 016103 0 ustar 00mg mg """
Convert IRC logs to HTML.
Usage: irclog2html.py filename
irclog2html will write out a colourised irc log, appending a .html
extension to the output file.
This is a Python port (+ improvements) of irclog2html.pl Version 2.1, which
was written by Jeff Waugh and is available at www.perkypants.org
"""
# Copyright (c) 2005--2014, Marius Gedminas
# Copyright (c) 2000, Jeffrey W. Waugh
# Python port:
# Marius Gedminas
# Original Author:
# Jeff Waugh
# Contributors:
# Rick Welykochy
# Alexander Else
# Ian Weller
#
# Released under the terms of the GNU GPL
# https://www.gnu.org/copyleft/gpl.html
# Differences from the Perl version:
# There are no hardcoded nick colour preferences for jdub, cantanker and
# chuckd
#
# Colours are preserver accross nick changes (irclog2html.pl tries to do
# that, but its regexes are buggy)
#
# irclog2html.pl interprets --colour-server #rrggbb as -s #rrggbb,
# irclog2html.py does not have this bug
#
# irclog2html.py understands ISO 8601 timestamps (YYYY-MM-DDTHH:MM:SS)
#
# New options: --title, --{prev,index,next}-{url,title} and many more
#
# New styles: xhtml, xhtmltable, mediawiki
#
# New default style: xhtmltable
#
import datetime
import gzip
import io
import itertools
import optparse
import os
import os.path
import re
import shlex
import shutil
import sys
from urllib.parse import quote
from ._version import __date__ as RELEASE
from ._version import __homepage__ as HOMEPAGE
from ._version import __version__ as VERSION
# If someone packages this for a Linux distro, they'll want to patch this to
# something like /usr/share/irclog2html/irclog.css, I imagine
CSS_FILE = os.path.join(os.path.dirname(__file__), 'irclog.css')
#
# Log parsing
#
class Enum(object):
"""Enumerated value."""
def __init__(self, value):
self.value = value
def __repr__(self):
return self.value
class LogParser(object):
"""Parse an IRC log file.
When iterated, yields the following events:
time, COMMENT, (nick, text)
time, ACTION, text
time, JOIN, text
time, PART, text,
time, NICKCHANGE, (text, oldnick, newnick)
time, SERVER, text
Text is a pure ASCII or Unicode string.
"""
COMMENT = Enum('COMMENT')
ACTION = Enum('ACTION')
JOIN = Enum('JOIN')
PART = Enum('PART')
NICKCHANGE = Enum('NICKCHANGE')
SERVER = Enum('SERVER')
OTHER = Enum('OTHER')
TIME_REGEXP = re.compile(
r'^\[?(' # Optional [
r'(?:\d{4}-\d{2}-\d{2}T|\d{2}-\w{3}-\d{4} |\w{3} \d{2} |\d{2} \w{3} )?' # Optional date
r'\d\d:\d\d(:\d\d)?' # Mandatory HH:MM, optional :SS
r')\]? +') # Optional ], mandatory space
TIMESTAMP_REGEXP = re.compile(r'^(\d+) +')
NICK_REGEXP = re.compile(r'^<(.*?)(!.*?)?>\s')
DIRCPROXY_NICK_REGEXP = re.compile(r'^<(.*?)(!.*)?>\s[\+-]?')
JOIN_REGEXP = re.compile(r'^(?:\*\*\*|-->|-!-)\s.*joined')
PART_REGEXP = re.compile(r'^(?:\*\*\*|<--|-!-)\s.*(quit|left)')
SERVMSG_REGEXP = re.compile(r'^(?:\*\*\*|---|-!-)\s')
NICK_CHANGE_REGEXP = re.compile(
r'^(?:\*\*\*|---|-!-)\s+(.*?) (?:are|is) now known as (.*)')
def __init__(self, infile, dircproxy=False):
self.infile = infile
if dircproxy:
self.NICK_REGEXP = self.DIRCPROXY_NICK_REGEXP
@staticmethod
def decode(s):
"""Convert 8-bit string to Unicode.
Supports xchat's hybrid Latin/Unicode encoding, as documented here:
http://xchat.org/encoding/
"""
if isinstance(s, str):
# Accept input that's already Unicode, for convenience
return s
try:
return s.decode('UTF-8')
except UnicodeError:
return s.decode('cp1252', 'replace')
def __iter__(self):
for line in self.infile:
line = self.decode(line).rstrip('\r\n')
if not line:
continue
m = self.TIME_REGEXP.match(line)
if m:
time = m.group(1)
line = line[len(m.group(0)):]
else:
time = None
if time is None:
m = self.TIMESTAMP_REGEXP.match(line)
if m:
time = datetime.datetime.fromtimestamp(
int(m.group(1)), datetime.timezone.utc
).strftime('%Y-%m-%dT%H:%M:%S')
line = line[len(m.group(0)):]
m = self.NICK_REGEXP.match(line)
if m:
nick = m.group(1)
text = line[len(m.group(0)):]
yield time, self.COMMENT, (nick, text)
elif line.startswith('* ') or line.startswith('*\t'):
yield time, self.ACTION, line
elif self.JOIN_REGEXP.match(line):
yield time, self.JOIN, line
elif self.PART_REGEXP.match(line):
yield time, self.PART, line
else:
m = self.NICK_CHANGE_REGEXP.match(line)
if m:
oldnick = m.group(1)
newnick = m.group(2)
yield time, self.NICKCHANGE, (line, oldnick, newnick)
elif self.SERVMSG_REGEXP.match(line):
yield time, self.SERVER, line
else:
yield time, self.OTHER, line
def open_log_file(filename):
"""Open a log file for parsing."""
# We're dealing with text here. Why open the file in binary mode?
# Simple: the Latin/Unicode hybrid encoding monstrosity described
# at http://xchat.org/encoding/#hybrid. Python doesn't support this
# natively, so we have to do the decoding ourselves.
if filename.endswith('.gz'):
return gzip.open(filename, 'rb')
else:
return open(filename, 'rb')
def shorttime(time):
"""Strip date and seconds from time.
>>> print(shorttime('12:45:17'))
12:45
>>> print(shorttime('12:45'))
12:45
>>> print(shorttime('2005-02-04T12:45'))
12:45
"""
if 'T' in time:
time = time.split('T')[-1]
if time.count(':') > 1:
time = ':'.join(time.split(':')[:2])
return time
#
# Colouring stuff
#
class ColourChooser:
"""Choose distinguishable colours."""
def __init__(self, rgbmin=240, rgbmax=125, a=0.95, b=0.5):
"""Define a range of colours available for choosing.
`rgbmin` and `rgbmax` define the outmost range of colour depth (note
that it is allowed to have rgbmin > rgbmax).
`rgb`, if specified, is a list of (r,g,b) values where each component
is between 0 and 1.0.
If `rgb` is not specified, then it is constructed as
[(a,b,b), (b,a,b), (b,b,a), (a,a,b), (a,b,a), (b,a,a)]
You can tune `a` and `b` for the starting and ending concentrations of
RGB.
"""
assert 0 <= rgbmin < 256
assert 0 <= rgbmax < 256
self.rgbmin = rgbmin
self.rgbmax = rgbmax
assert 0 <= a <= 1.0
assert 0 <= b <= 1.0
self.rgb = [
(a, b, b),
(b, a, b),
(b, b, a),
(a, a, b),
(a, b, a),
(b, a, a),
]
def choose(self, i, n):
"""Choose a colour.
`n` specifies how many different colours you want in total.
`i` identifies a particular colour in a set of `n` distinguishable
colours.
Returns a string '#rrggbb'.
"""
if n == 0:
n = 1
r, g, b = self.rgb[i % len(self.rgb)]
m = self.rgbmin + (self.rgbmax - self.rgbmin) * float(n - i) / n
r, g, b = [int(c * m) for c in [r, g, b]]
assert 0 <= r < 256
assert 0 <= g < 256
assert 0 <= b < 256
return '#%02x%02x%02x' % (r, g, b)
class NickColourizer:
"""Choose distinguishable colours for nicknames."""
def __init__(self, maxnicks=30, colour_chooser=None):
"""Create a colour chooser for nicknames.
If you know how many different nicks there might be, specify that
numer as `maxnicks`. If you don't know, don't worry.
If you really want to, you can specify a colour chooser. Default is
ColourChooser().
"""
if colour_chooser is None:
colour_chooser = ColourChooser()
self.colour_chooser = colour_chooser
self.nickcount = 0
self.maxnicks = maxnicks
self.nick_colour = {}
def __getitem__(self, nick):
colour = self.nick_colour.get(nick)
if not colour:
self.nickcount += 1
if self.nickcount >= self.maxnicks:
self.maxnicks *= 2
colour = self.colour_chooser.choose(self.nickcount, self.maxnicks)
self.nick_colour[nick] = colour
return colour
def change(self, oldnick, newnick):
if oldnick in self.nick_colour:
self.nick_colour[newnick] = self.nick_colour.pop(oldnick)
#
# HTML
#
URL_REGEXP = re.compile(r'((http|https|ftp|gopher|news)://([.,]*([^ \'")>&.,]|&))*)')
def createlinks(text):
"""Replace possible URLs with links.
>>> print(createlinks('check out <http://example.com/a?b=c&c=d#e>!'))
check out <http://example.com/a?b=c&c=d#e>!
>>> print(createlinks('http://example.com/a,'))
http://example.com/a,
>>> print(createlinks('http://example.com/a.'))
http://example.com/a.
>>> print(createlinks('http://example.com/a.b'))
http://example.com/a.b
"""
return URL_REGEXP.sub(r'\1', text)
def escape(s):
"""Replace ampersands, pointies, control characters.
>>> print(escape('"Hello" & '))
"Hello" & <world>
Control characters (ASCII 0 to 31) are stripped away
>>> print(escape('[%s]' % ''.join([chr(x) for x in range(32)])))
[]
"""
s = s.replace('&', '&').replace('<', '<').replace('>', '>').replace('"', '"')
return ''.join([c for c in s if ord(c) > 0x1F])
#
# Output styles
#
class AbstractStyle(object):
"""A style defines the way output is formatted.
This is not a real class, rather it is an description of how style
classes should be written.
"""
name = "stylename"
description = "Single-line description"
charset = 'US-ASCII'
def __init__(self, outfile, *, outfilename='', colours=None):
"""Create a text formatter for writing to outfile.
The ``colours`` dictionary may have the following items:
- part
- join
- server
- nickchange
- action
"""
self.outfile = io.TextIOWrapper(outfile, encoding=self.charset,
errors='xmlcharrefreplace',
line_buffering=True)
self.outfilename = os.path.basename(outfilename)
self.colours = colours or {}
self._anchors = set()
def __del__(self):
"""Destructor to make sure we don't close outfile prematurely."""
if not self.outfile.closed:
self.outfile.flush()
self.outfile.detach() # don't let TextIOWrapper.__del__ close it!
def head(self, title, prev=('', ''), index=('', ''), next=('', ''),
searchbox=False):
"""Generate the header.
`prev`, `index` and `next` are tuples (title, url) that comprise
the navigation bar.
"""
def foot(self):
"""Generate the footer."""
def servermsg(self, time, what, line):
"""Output a generic server message.
`time` is a string.
`line` is not escaped.
`what` is one of LogParser event constants (e.g. LogParser.JOIN).
"""
def nicktext(self, time, nick, text, htmlcolour):
"""Output a comment uttered by someone.
`time` is a string.
`nick` and `text` are not escaped.
`htmlcolour` is a string ('#rrggbb').
"""
def timestamp_anchor(self, time):
anchor = 't%s' % time
if anchor in self._anchors:
org_anchor = anchor
for n in itertools.count(2):
anchor = '%s-%d' % (org_anchor, n)
if anchor not in self._anchors:
break
self._anchors.add(anchor)
return anchor
class SimpleTextStyle(AbstractStyle):
"""Text style with little use of colour"""
name = "simplett"
description = __doc__
charset = 'iso-8859-1'
def head(self, title, prev=None, index=None, next=None, searchbox=False):
print("""\
\t%(title)s
\t
\t
\t
\t
""" % {
'VERSION': VERSION,
'RELEASE': RELEASE,
'title': escape(title),
'charset': self.charset,
}, file=self.outfile)
def foot(self):
print("""
Generated by irclog2html.py %(VERSION)s by Marius Gedminas
- find it at %(HOMEPAGE)s!
""" % {'VERSION': VERSION,
'HOMEPAGE': escape(HOMEPAGE)},
end=' ', file=self.outfile)
def servermsg(self, time, what, text):
text = escape(text)
text = createlinks(text)
colour = self.colours.get(what)
if colour:
text = '%s' % (colour, text)
self._servermsg(text)
def _servermsg(self, line):
print('%s ' % line, file=self.outfile)
def nicktext(self, time, nick, text, htmlcolour):
nick = escape(nick)
text = escape(text)
text = createlinks(text)
text = text.replace(' ', ' ')
self._nicktext(time, nick, text, htmlcolour)
def _nicktext(self, time, nick, text, htmlcolour):
print('<%s> %s ' % (nick, text), file=self.outfile)
class TextStyle(SimpleTextStyle):
"""Text style using colours for each nick"""
name = "tt"
description = __doc__
def _nicktext(self, time, nick, text, htmlcolour):
print('<%s>'
' %s '
% (htmlcolour, nick, text), file=self.outfile)
class SimpleTableStyle(SimpleTextStyle):
"""Table style, without heavy use of colour"""
name = "simpletable"
def head(self, title, prev=None, index=None, next=None, searchbox=False):
SimpleTextStyle.head(self, title, prev, index, next, searchbox)
print("
'
% (htmlcolour, nick, text), file=self.outfile)
class TableStyle(SimpleTableStyle):
"""Default style, using a table with bold colours"""
name = "table"
description = __doc__
def _nicktext(self, time, nick, text, htmlcolour):
print('
'
'%s
'
'
%s
'
% (htmlcolour, nick, htmlcolour, text), file=self.outfile)
class XHTMLStyle(AbstractStyle):
"""Text style, produces XHTML that can be styled with CSS"""
name = 'xhtml'
description = __doc__
charset = 'UTF-8'
CLASSMAP = {
LogParser.ACTION: 'action',
LogParser.JOIN: 'join',
LogParser.PART: 'part',
LogParser.NICKCHANGE: 'nickchange',
LogParser.SERVER: 'servermsg',
LogParser.OTHER: 'other',
}
prefix = '
' % escape(title), file=self.outfile)
def link(self, url, title):
# Intentionally not escaping title so that &entities; work
if url:
print('%s'
% (escape(quote(url)), title or escape(url)),
end=' ', file=self.outfile)
elif title:
print('%s' % title,
end=' ', file=self.outfile)
def searchbox(self):
print("""
""", file=self.outfile)
def navbar(self, prev, index, next):
prev_title, prev_url = prev
index_title, index_url = index
next_title, next_url = next
if not (prev_title or index_title or next_title or
prev_url or index_url or next_url):
return
print('
""" % {'VERSION': VERSION,
'HOMEPAGE': escape(HOMEPAGE)}, file=self.outfile)
def servermsg(self, time, what, text):
"""Output a generic server message.
`time` is a string.
`line` is not escaped.
`what` is one of LogParser event constants (e.g. LogParser.JOIN).
"""
text = escape(text)
text = createlinks(text)
if time:
print(
'
'.format(
css_class=self.CLASSMAP[what], text=text),
file=self.outfile)
def nicktext(self, time, nick, text, htmlcolour):
"""Output a comment uttered by someone.
`time` is a string.
`nick` and `text` are not escaped.
`htmlcolour` is a string ('#rrggbb').
"""
nick = escape(nick)
text = escape(text)
text = createlinks(text)
text = text.replace(' ', ' ')
if time:
print(
'
'.format(
color=htmlcolour,
nick=nick,
text=text),
file=self.outfile)
class XHTMLTableStyle(XHTMLStyle):
"""Table style, produces XHTML that can be styled with CSS"""
name = 'xhtmltable'
description = __doc__
prefix = '
'
suffix = '
'
def servermsg(self, time, what, text, link=''):
text = escape(text)
text = createlinks(text)
if time:
print(
'
'.format(
css_class=self.CLASSMAP[what],
text=text),
file=self.outfile)
def nicktext(self, time, nick, text, htmlcolour, link=''):
nick = escape(nick)
text = escape(text)
text = createlinks(text)
text = text.replace(' ', ' ')
link = link or self.outfilename
if time:
print(
'
'.format(
color=htmlcolour,
nick=nick,
text=text),
file=self.outfile)
class MediaWikiStyle(AbstractStyle):
"""Table style, produces MediaWiki syntax"""
name = 'mediawiki'
description = __doc__
def head(self, title, prev=('', ''), index=('', ''), next=('', ''),
searchbox=False):
print('{|', file=self.outfile)
def servermsg(self, time, what, text, link=''):
text = escape(text)
# no need to call createlinks, MediaWiki parses links automatically
if time:
displaytime = shorttime(time)
print('|- id="t%s"\n'
'| colspan="2" | %s\n'
'|| [[#t%s|%s]]'
% (time, text, time, displaytime), file=self.outfile)
else:
print('|-\n'
'| colspan="3" | %s' % text, file=self.outfile)
def nicktext(self, time, nick, text, htmlcolour, link=''):
nick = escape(nick)
text = escape(text)
# no need to call createlinks, MediaWiki parses links automatically
if time:
displaytime = shorttime(time)
print('|- id="t%s"\n'
'! style="background-color: %s" | %s\n'
'| style="color: %s" | %s\n'
'|| [[#t%s|%s]] '
% (time, htmlcolour, nick, htmlcolour, text,
time, displaytime), file=self.outfile)
else:
print('|-\n'
'| style="background-color: %s" | %s\n'
'| style="color: %s" colspan="2" | %s '
% (htmlcolour, nick, htmlcolour, text), file=self.outfile)
def foot(self):
print('|}\n\nGenerated by irclog2html.py %(VERSION)s '
'by [mailto:marius@pov.lt Marius Gedminas] - '
'find it at [%(HOMEPAGE)s %(HOMEPAGE)s]!'
% {'VERSION': VERSION, 'HOMEPAGE': HOMEPAGE}, file=self.outfile)
#
# Main
#
# All styles
STYLES = [
SimpleTextStyle,
TextStyle,
SimpleTableStyle,
TableStyle,
XHTMLStyle,
XHTMLTableStyle,
MediaWikiStyle,
]
# Customizable colours
COLOURS = [
("part", "#000099", LogParser.PART),
("join", "#009900", LogParser.JOIN),
("server", "#009900", LogParser.SERVER),
("nickchange", "#009900", LogParser.NICKCHANGE),
("action", "#CC00CC", LogParser.ACTION),
]
def do_config_file(option, opt_str, value, parser):
"""Read options from a config file and feed them back to optparse."""
options = []
try:
with open(value) as f:
for line in f:
line = line.strip()
if not line or line.startswith('#'):
continue
options.extend(shlex.split(line))
# Note: you can cause an infinite loop if you have a config file that
# includes itself! Well, cause a RuntimeError actually.
parser.rargs[:0] = options
except IOError as e:
raise optparse.OptionValueError("can't read config file: %s" % e)
def parse_args(argv=sys.argv):
parser = optparse.OptionParser("usage: %prog [options] filename [...]",
version=VERSION,
prog='irclog2html',
description="Colourises and converts IRC"
" logs to HTML format for easy"
" web reading.")
parser.add_option('-c', '--config', action='callback', type='str',
metavar='FILE', callback=do_config_file,
help="read options from a config file")
parser.add_option('--dircproxy', action='store_true', default=False,
help="dircproxy log file support (strips leading + or - from messages; off by default)")
parser.add_option('-s', '--style', dest="style", default="xhtmltable",
help="format log according to specific style"
" (default: xhtmltable); try -s help for a list of"
" available styles")
parser.add_option('-t', '--title', dest="title", default=None,
help="title of the page (default: same as file name)")
parser.add_option('--prev-title', dest="prev_title", default='',
help="title of the previous page (default: none)")
parser.add_option('--prev-url', dest="prev_url", default='',
help="URL of the previous page (default: none)")
parser.add_option('--index-title', dest="index_title", default='',
help="title of the index page (default: none)")
parser.add_option('--index-url', dest="index_url", default='',
help="URL of the index page (default: none)")
parser.add_option('--next-title', dest="next_title", default='',
help="title of the next page (default: none)")
parser.add_option('--next-url', dest="next_url", default='',
help="URL of the next page (default: none)")
parser.add_option('-S', '--searchbox', action="store_true", dest="searchbox",
default=False,
help="include a search box")
parser.add_option('-o', '--output-file',
help="destination output file or directory"
" (default: .html)")
for name, default, what in COLOURS:
parser.add_option('--color-%s' % name, '--colour-%s' % name,
dest="colour_%s" % name, default=default,
help="select %s colour (default: %s)"
% (name, default))
options, args = parser.parse_args(argv[1:])
return parser, options, args
def pick_output_filename(input_filename):
"""Pick a filename for the output file."""
if input_filename.endswith('.gz'):
return input_filename[:-len('.gz')] + ".html"
else:
return input_filename + ".html"
def main(argv=sys.argv):
parser, options, args = parse_args(argv)
if options.style == "help":
print("The following styles are available for use with irclog2html.py:")
for style in STYLES:
print()
print(" %s" % style.name)
print(" %s" % style.description)
print()
return
for style in STYLES:
if style.name == options.style:
break
else:
parser.error("unknown style: %s" % options.style)
colours = {}
for name, default, what in COLOURS:
colours[what] = getattr(options, 'colour_%s' % name)
if not args:
parser.error("please specify a filename")
title = options.title
prev = (options.prev_title, options.prev_url)
index = (options.index_title, options.index_url)
next = (options.next_title, options.next_url)
if len(args) > 1 and options.output_file and not os.path.isdir(options.output_file):
parser.error("-o must be a directory when processing multiple files")
for filename in args:
try:
infile = open_log_file(filename)
except EnvironmentError as e:
sys.exit("%s: cannot open %s for reading: %s"
% (parser.prog, filename, e))
# Why open the output file in binary mode? We currently handle
# encoding in our style classes, and they have different default
# charsets, so it's simpler to just give a binary file to the
# style class and let it deal with all the details.
if not options.output_file:
outfilename = pick_output_filename(filename)
elif os.path.isdir(options.output_file):
outfilename = os.path.join(
options.output_file,
os.path.basename(pick_output_filename(filename)))
else:
outfilename = options.output_file
try:
outfile = open(outfilename, "wb")
except EnvironmentError as e:
infile.close()
sys.exit("%s: cannot open %s for writing: %s"
% (parser.prog, outfilename, e))
try:
parser = LogParser(infile, dircproxy=options.dircproxy)
formatter = style(outfile, outfilename=outfilename, colours=colours)
convert_irc_log(parser, formatter, title or filename,
prev, index, next, searchbox=options.searchbox)
css_file = os.path.join(os.path.dirname(outfilename), 'irclog.css')
if not os.path.exists(css_file) and os.path.exists(CSS_FILE):
shutil.copy(CSS_FILE, css_file)
finally:
outfile.close()
infile.close()
def convert_irc_log(parser, formatter, title, prev, index, next,
searchbox=False):
"""Convert IRC log to HTML or some other format."""
nick_colour = NickColourizer()
formatter.head(title, prev, index, next, searchbox=searchbox)
for time, what, info in parser:
if what == LogParser.COMMENT:
nick, text = info
htmlcolour = nick_colour[nick]
formatter.nicktext(time, nick, text, htmlcolour)
else:
if what == LogParser.NICKCHANGE:
text, oldnick, newnick = info
nick_colour.change(oldnick, newnick)
else:
text = info
formatter.servermsg(time, what, text)
formatter.foot()
if __name__ == '__main__':
main()
././@PaxHeader 0000000 0000000 0000000 00000000026 00000000000 010213 x ustar 00 22 mtime=1714731170.0
irclog2html-4.0.0/porting/test.py 0000775 0001750 0001750 00000010660 14615134242 014616 0 ustar 00mg mg #!/usr/bin/env python
"""
Functional tests for irclog2html.py
You must run this script in a directory that contains irclog2html.py,
irclog2html.pl and testcases/*.log. Both scripts must be executable.
"""
import difflib
import glob
import os
import shutil
import tempfile
from irclog2html import RELEASE, VERSION
def replace(s, replacements):
"""Replace a bunch of things in a string."""
replacements = [(-len(k), k, v) for k, v in replacements.iteritems()]
replacements.sort() # longest first
for sortkey, k, v in replacements:
s = s.replace(k, v)
return s
def run_in_tempdir(inputfile, script, args):
"""Copy inputfile into a temporary directory and run a given command.
Arguments for the script are args with the name of the copied file
appended (e.g. run('/var/log/irc.log', 'irclog2html.py', '-s table')
will run irclog2html.py -s table /tmp/tempdirname/irc.log)
Performs no shell escaping whatsoever.
Returns the contents of the output file (inputfile + '.html' in the
temporary directory).
"""
dir = tempfile.mkdtemp()
try:
newinputfile = os.path.join(dir, os.path.basename(inputfile))
shutil.copyfile(inputfile, newinputfile)
cmdline = '%s %s %s' % (script, args, newinputfile)
pipe = os.popen('%s 2>&1' % cmdline, 'r')
output = pipe.read()
status = pipe.close()
if status:
raise AssertionError('%s returned status code %s\n%s'
% (cmdline, status, output))
if output:
raise AssertionError('%s said\n%s'
% (cmdline, output))
outfilename = newinputfile + '.html'
try:
return open(outfilename).read().replace(dir, '/tmpdir')
except IOError as e:
raise AssertionError('%s did not create the output file\n%s' %
(cmdline, e))
finally:
shutil.rmtree(dir)
def run_and_compare(inputfile, args=""):
"""Run irclog2html.pl and irclog2html.py on inputfile and compare outputs.
args specify additional command line arguments.
"""
output1 = run_in_tempdir(inputfile, './irclog2html.py', args)
output1 = replace(output1, {'irclog2html.py': 'SCRIPT',
'Marius Gedminas': 'AUTHOR',
VERSION: 'VERSION',
RELEASE: 'REVISION',
'marius@pov.lt': 'EMAIL',
'https://mg.pov.lt/irclog2html/': 'URL',
'mg.pov.lt': 'WEBSITE'})
output2 = run_in_tempdir(inputfile, './irclog2html.pl', args)
output2 = replace(output2, {'irclog2html.pl': 'SCRIPT',
'Jeff Waugh': 'AUTHOR',
'2.1mg': 'VERSION',
'27th July, 2001': 'REVISION',
'jdub@NOSPAMperkypants.org': 'EMAIL',
'http://freshmeat.net/projects/irclog2html.pl/':
'URL',
'freshmeat.net': 'WEBSITE'})
if output1 != output2:
raise AssertionError('files differ (- irclog2html.py,'
' + irclog2html.pl):\n' +
''.join(difflib.ndiff(output1.splitlines(True),
output2.splitlines(True))))
DEFAULT_ARGS = ('-s table', '-s simplett', '-s tt', '-s simpletable',
'-s table --colour-part="#deadbe"',
'-s table --color-action=#cafeba')
def testcase(inputfile, args_to_try=DEFAULT_ARGS):
"""Run both scripts on inputfile with various arguments."""
print(inputfile),
try:
for args in args_to_try:
print(".", end='')
run_and_compare(inputfile, args)
except AssertionError as e:
print("FAILED")
print()
print(e)
print()
else:
print("ok")
def main():
os.chdir(os.path.dirname(__file__))
# the Perl script takes ages to process dircproxy-example.log; ignore it
testcases = glob.glob('testcases/test*.log')
print("Comparing outputs produced by the Perl version and the Python port")
print("There are %d test cases" % len(testcases))
n = 0
for inputfile in testcases:
n += 1
print(n, end='')
testcase(inputfile)
if __name__ == '__main__':
main()
././@PaxHeader 0000000 0000000 0000000 00000000034 00000000000 010212 x ustar 00 28 mtime=1729164244.0683556
irclog2html-4.0.0/porting/testcases/ 0000775 0001750 0001750 00000000000 14704171724 015262 5 ustar 00mg mg ././@PaxHeader 0000000 0000000 0000000 00000000026 00000000000 010213 x ustar 00 22 mtime=1560428581.0
irclog2html-4.0.0/porting/testcases/dircproxy-example.log 0000644 0001750 0001750 00002352155 13500440045 021440 0 ustar 00mg mg [14 Jan 10:36] --> jsmith (n=user@68-246-114-6.area3.spcsdns.net) joined the channel
[14 Jan 11:08] --> jsmith (n=jsmith@72.21.36.138) joined the channel
[14 Jan 11:32] *** You disconnected
[14 Jan 12:35] --> nombyte (n=nmcbride@208.176.91.226.ptr.us.xo.net) joined the channel
[14 Jan 12:36] -hey doesn't anyone know a fedora app that can be used to make java gui's?
[14 Jan 12:37] +No clue... there's probably an Eclipse plugin that does it
[14 Jan 12:37] +But I don't claim to know anything about Java
[14 Jan 12:37] -me either thats why im trying to learn
[14 Jan 12:37] -i searched for it but came up blank...
[14 Jan 12:41] -i keep seeing stuff about awt and jfc but it has all confused me...
[14 Jan 12:53] *** You connected
[14 Jan 15:11] *** You disconnected
[14 Jan 15:12] *** You connected
[14 Jan 15:12] *** You disconnected
[14 Jan 15:12] *** You connected
[14 Jan 16:47] *** You disconnected
[14 Jan 16:59] --> quigleymd (n=quigley@c-24-30-241-47.hsd1.va.comcast.net) joined the channel
[14 Jan 19:15] *** You connected
[14 Jan 20:03] *** You disconnected
[14 Jan 20:09] *** You connected
[14 Jan 21:27] *** You disconnected
[14 Jan 21:27] *** You connected
[14 Jan 23:06] -hey if u ssh into a box and run a script with & at the end of it to background it, if u end ur ssh session will it still run?
[14 Jan 23:26] nombyte: Yes, it'll keep running just fine.
[14 Jan 23:35] +k
[15 Jan 00:53] *** You disconnected
[15 Jan 07:23] *** You connected
[15 Jan 08:42] +
[15 Jan 08:42] * jsmith-away wanders away...
[15 Jan 09:15] -morning...
[15 Jan 11:28] *** You disconnected
[15 Jan 12:22] +It's snowing!
[15 Jan 12:52] +lol - work_a ;)
[15 Jan 12:52] +hitting the work load huh stickster?
[15 Jan 12:55] +plarsen: If you haven't heard, Paul is in the process of changing jobs, and will be the new Fedora Project leader
[15 Jan 12:56] +plarsen: So he's very busy between trying to wrap some things up at his old job, as well as take over the Fedora Project, trying to fix up his house to get ready to sell, find a new house, etc.
[15 Jan 12:56] +plarsen: Not to mention he was out of town all weekend
[15 Jan 12:57] +lol - yeah I saw he was looking at North Carolina ;) So I was about to make a joke or two about going to the "enemy" ;)
[15 Jan 12:57] +Naw, he'll be working out the Westford offices near Boston
[15 Jan 12:57] +We'll have to doube our efforts to keep the meetings going without good old stickster ;)
[15 Jan 12:58] +ohhh - I thought it said NC ?
[15 Jan 12:58] +Yes... and I hereby elect you to be the new puppet dictator for life!
[15 Jan 12:58] +infobot: Say "I agree"
[15 Jan 12:58] +"I agree"
[15 Jan 12:58] +lol
[15 Jan 12:58] +We have concensus!
[15 Jan 12:58] +This was so easy!
[15 Jan 12:59] +nope, yoiu just had a "second" - there wasn't a vote yet ;)
[15 Jan 12:59] +No, it was an impromptu vote
[15 Jan 12:59] +All in favor, say "Aye"
[15 Jan 12:59] +infobot: Say "Aye!"
[15 Jan 12:59] +"Aye!"
[15 Jan 12:59] +Aye!
[15 Jan 13:00] +We have more than 50% of the respondents saying Aye, so the motion is passed!
[15 Jan 13:00] +
[15 Jan 13:00] * jsmith pounds his gavel on the table
[15 Jan 14:32] +lol
[15 Jan 14:32] +A "minority dictatorship" :)
[15 Jan 16:28] +plarsen: What do you mean minority -- infobot and I both voted for you, and I didn't hear *anyone* vote against you
[15 Jan 16:29] +you must be american born ... voting AGAINST someone? Since when is that done?? :D
[15 Jan 16:29] +;-)
[15 Jan 16:30] +Guilty as charged!
[15 Jan 16:58] +hey guys
[15 Jan 16:58] +you around?
[15 Jan 16:58] +i just got back to the state, and saw the emails re: the press release
[15 Jan 17:01] +Yeah, I'm here
[15 Jan 17:01] +Wassup?
[15 Jan 17:01] +you check the listserv today?
[15 Jan 17:01] +You hear about our fearless leader yet?
[15 Jan 17:01] +yea
[15 Jan 17:01] +i congratulated him!
[15 Jan 17:02] +im happy for him
[15 Jan 17:02] +and wish him nothing but great success :D
[15 Jan 17:05] +soo... any idea how to write a press release
[15 Jan 17:05] +newely nominated community relations manager ;)
[15 Jan 17:09] +Uh, no
[15 Jan 17:09] +press release, eh?
[15 Jan 17:10] +I thought we just needed somebody to call the Free-Lance Star and say "Hey, put us on the calendar."
[15 Jan 17:11] +But then again, I haven't checked the list today
[15 Jan 17:11] +Been busy
[15 Jan 17:21] +"the busy pinguins" - that's Fredlugs subtitle :)
[15 Jan 17:22] +hey, did I tell ya novalug had their monthly thing at Oracle in Reston? They have a great sign at the entrance with Tux'es crossing the road warning you to drive carefully :D
[15 Jan 17:22] +that was SOOO way cute!!
[15 Jan 17:23] +plarsen: You should have taken a picture!
[15 Jan 17:23] +I will next month!!
[15 Jan 17:57] *** You connected
[15 Jan 18:00] +sorry to run off i got sidetracked
[15 Jan 18:03] +quigleymd: No problem... I've gotta run to Scouts
[15 Jan 18:04] +
[15 Jan 18:04] * jsmith-away wanders away...
[15 Jan 19:05] quigleymd: Hey man!
[15 Jan 19:06] +stickster: hey man!
[15 Jan 19:06] +stickster: you have uncanny timing
[15 Jan 19:06] +i just got home from work!
[15 Jan 19:06] +CONGRATULATIONS!
[15 Jan 19:06] Thanks :-)
[15 Jan 19:07] +was it expected?
[15 Jan 19:07] Well, it's been cooking for a while
[15 Jan 19:07] +:)
[15 Jan 19:07] +good for you
[15 Jan 19:07] But I didn't expect the offer to be good enough to take :-D
[15 Jan 19:07] +HAH
[15 Jan 19:07] +will it be less than a 70 mile commute :D
[15 Jan 19:07] They proved me wrong, so now we're headed to NH!
[15 Jan 19:08] +i just got back from MA today
[15 Jan 19:08] +very pretty...
[15 Jan 19:08] Yeah, actually I'll probably end up around Nashua, which is only about 35 min from the office
[15 Jan 19:08] Lotsa white stuff I hear
[15 Jan 19:08] +as the snow was still all white cus it just fell yesterday
[15 Jan 19:08] I like winter. Even snowy winter.
[15 Jan 19:08] Summer, not so much.
[15 Jan 19:08] +im with ya man :)
[15 Jan 19:08] Hey, it gets hot enough to swim there, that's good enough for me
[15 Jan 19:09] A friend gave me lots of information on the NH areas to look at
[15 Jan 19:09] +just make sure your new house has an indoor pool ;)
[15 Jan 19:09] Right :-D
[15 Jan 19:09] They're not paying me THAT much
[15 Jan 19:09] +:D
[15 Jan 19:11] So my last day is Friday Feb 1
[15 Jan 19:11] quigleymd: Make sure you let me know if you don't see an announcemtn in the next day or two
[15 Jan 19:11] *announcement
[15 Jan 19:11] +wheres the honorary luncheon :D
[15 Jan 19:11] I'm hoping they'll just send an all-OTD mail
[15 Jan 19:12] +stickster: i will, i havent checked my junk mail since around mid january
[15 Jan 19:12] +oops s/january/december
[15 Jan 19:12] Well, we haven't really picked it quite yet
[15 Jan 19:12] I guess I need to do that.
[15 Jan 19:12] +but i'll clean it out tomoorw and keep my eyes open
[15 Jan 19:13] Cool
[15 Jan 19:13] +stickster: so did it go over well over there?
[15 Jan 19:13] It went GREAT.
[15 Jan 19:13] We should get together for a lunch
[15 Jan 19:14] +most definitely
[15 Jan 19:14] +hows thurs look for you?
[15 Jan 19:14] Maybe everyone can do Friday or something
[15 Jan 19:14] +im OOT
[15 Jan 19:14] Thursday is good I think too
[15 Jan 19:14] +F-M
[15 Jan 19:14] Shall I pencil in Thursday then?
[15 Jan 19:14] +definitely
[15 Jan 19:14] Pancho? Somewhere else?
[15 Jan 19:14] * stickster is open to suggestions
[15 Jan 19:14] +wherever you'd like, we eat out 4.7 times a week
[15 Jan 19:15] +jsmith-away: take note, you have lunch plans on thursday
[15 Jan 19:15] +:)
[15 Jan 19:16] heh
[15 Jan 19:16] +stickster: they taking care of the move too?
[15 Jan 19:16] quigleymd: Yeah, the deal worked out pretty good.
[15 Jan 19:17] I mean, they're not handing me big bags o' cash, but it will be enough that we can make things work fine
[15 Jan 19:17] I'm a little bummed that I'm probably going to have to price my house to sell
[15 Jan 19:17] And I am REALLY upset at how much realtors end up costing when your house has gone up in value :-D
[15 Jan 19:17] +yea, i think you're right on that one
[15 Jan 19:18] +the rich get richer...
[15 Jan 19:18] They gave me 9 months to get there
[15 Jan 19:18] +oh wow
[15 Jan 19:18] I can remote until then
[15 Jan 19:18] But I feel like if I don't get to the office soon it will put me at a disadvantage
[15 Jan 19:18] +maybe summer will see things turn around..
[15 Jan 19:18] Well, can't wait that long I think.
[15 Jan 19:18] +Ic
[15 Jan 19:19] +you're going to be a good czar :)
[15 Jan 19:19] They're being really superflexible, I think that I'm the one who is making it into a "must-do-now" thing
[15 Jan 19:19] hang on, brb
[15 Jan 19:19] +10-4, i dont blame you for getting on with it
[15 Jan 19:22] Just putting something on the tube for the kids until bedtime
[15 Jan 19:23] +so is the rest of the fam as excited as you?
[15 Jan 19:23] quigleymd: I think so
[15 Jan 19:23] At first we thought we'd be going to Raleigh, but it became really clear that the best way to do this job was in Westford
[15 Jan 19:24] A lot of it involves communication with the Engineering folks up there, lots of RHEL managers
[15 Jan 19:24] +so MA is where all the real work gets done?
[15 Jan 19:24] So doing that f2f is probably a lot better... plus there's a big Fedora staff there, lots of the folks I know... Jesse Keating, Jeremy Katz, Tom Callaway, Luke Macken, etc.
[15 Jan 19:25] quigleymd: Yeah, at least the coding work
[15 Jan 19:25] There are a few engineers in Raleigh, but about 95% of those guys are in MA.
[15 Jan 19:25] Bill Nottingham, for example, is in NC.
[15 Jan 19:25] So I start orientation on the 4th, but I'm staying a whole week to make meetings with Legal, Marketing/BrandComm, GLS, etc.
[15 Jan 19:26] +im guessing you're planning on leaving the fam here for a bit?
[15 Jan 19:27] quigleymd: Well, just for when I do my orientation
[15 Jan 19:27] And I might have to do a trip to BOS for maybe a week too
[15 Jan 19:27] But really, no
[15 Jan 19:27] +well give a shout if you need anything
[15 Jan 19:27] Since I can remote for <= 9months, we can all move together
[15 Jan 19:28] Originally I was thinking we needed to sell and buy at the same time, which would have been... well, hard.
[15 Jan 19:28] +ahh i got the impression that you wanted to be there 4 weeks a month
[15 Jan 19:28] +starting in feb
[15 Jan 19:28] Well, I do want to be there ASAP, but not without them :-)
[15 Jan 19:28] +:)
[15 Jan 19:28] I'm increasingly thinking (thanks to wiser friends) that we should rent for a few months up in NH and then buy a place
[15 Jan 19:28] Probably easier even if it means moving twice
[15 Jan 19:29] +I think i'd agree too
[15 Jan 19:29] I can't believe I'm going to work in the same company as Alan (#*%&ing Cox!
[15 Jan 19:30] +:D
[15 Jan 19:30] Oh yeah, and Dave Jones... Greg DeKoenigsberg...
[15 Jan 19:30] +you da man
[15 Jan 19:30] +:D
[15 Jan 19:30] not me
[15 Jan 19:30] I just hang around with people who are da man
[15 Jan 19:30] +HAH
[15 Jan 19:30] +*whatever*
[15 Jan 19:30] But I can be a good figurehead apparently
[15 Jan 19:30] Lots of hot air and not much substance, y'know
[15 Jan 19:30] +indeed i do
[15 Jan 19:31] FUDCon was awesome
[15 Jan 19:31] We should definitely get you involved so you could meet some of the hackers
[15 Jan 19:31] +everything go fine with the airport shuffle and jsmith?
[15 Jan 19:31] Just fine
[15 Jan 19:31] His plane was delayed until almost 1am, but it was no big deal
[15 Jan 19:31] Easy drive
[15 Jan 19:31] +wow, I thought the whole city of Richmond closed at 9
[15 Jan 19:32] Well, this was picking him up at RDU
[15 Jan 19:32] +yea, I'd like to swing FUDCon sometimes
[15 Jan 19:32] I dropped him off at RIC on Sunday night, no problem there either
[15 Jan 19:32] +I was hoping to get a RH certification one of these years..
[15 Jan 19:32] +ahh
[15 Jan 19:32] +well good
[15 Jan 19:32] quigleymd: So you do Linux development stuff at work, right?
[15 Jan 19:32] +VERY little
[15 Jan 19:32] Hm
[15 Jan 19:33] Well, there will be another FUDCon style hackfest and Fedora sessions at the Red Hat Summit in Boston in June
[15 Jan 19:33] +that sounds like it could be a very good time
[15 Jan 19:33] You should try and make that GETA training. It's actually a pretty cheap treat
[15 Jan 19:33] +ill mark it on the calendar :)
[15 Jan 19:34] ISTR it's like $995 for registration and entry to everything
[15 Jan 19:34] +that is cheap
[15 Jan 19:34] So with travel, RIC -> BOS you should be able to bring it in for well under $2K
[15 Jan 19:34] +most def
[15 Jan 19:34] +our unit is (or at least has been) really good about training too
[15 Jan 19:35] You can see as much RHEL stuff as you want, meet the F Project guys at the hackfest, come out with us for the parties at night (to the extent you like that sort of thing)
[15 Jan 19:35] +im sold.
[15 Jan 19:35] Cool, I'm holding you to it :-)
[15 Jan 19:35] And maybe jsmith-away too if he can swing it
[15 Jan 19:36] +sounds like community relations to me :)
[15 Jan 19:36] Exactly
[15 Jan 19:36] jsmith-away is so excited -- I think he really had a great time there
[15 Jan 19:36] And I got him hooked up with Mike McGrath, our Infrastructure community honcho
[15 Jan 19:36] They may be working up some Asterisk stuff for us, and hopefully a couple other cool projects
[15 Jan 19:37] +an open souce company using an open source pbx?
[15 Jan 19:37] +:p
[15 Jan 19:37] Well, at least for Fedora, I mean
[15 Jan 19:37] I told him he needs to work that other angle too ;-)
[15 Jan 19:37] +i think its a great idea
[15 Jan 19:37] All right, I'm gonna run to another desktop to do some work, but feel free to shout at me if you need something
[15 Jan 19:37] +sure, you too
[15 Jan 19:38] +and like i said, let us know if you need anything
[15 Jan 19:38] +as we're local :)
[15 Jan 19:39] I will, you guys are the greatest
[15 Jan 19:39] quigleymd: Do you want some lamps by any chance?
[15 Jan 19:39] In perfectly good shape, just we don't want them anymore (and anything we don't want and have to move, we just have to find a place for later)
[15 Jan 19:40] * stickster runs afk for a bit for kids' story time and bedtime
[15 Jan 20:38] jsmith-away: Help!
[15 Jan 20:39] Who ate with us on Friday night? You, me, Clint, Toshio, Michael DeHaan, Chris Negus, and... ?
[16 Jan 00:00] *** You disconnected
[16 Jan 07:44] *** You connected
[16 Jan 07:47] *** You disconnected
[16 Jan 07:47] *** You connected
[16 Jan 10:51] *** You disconnected
[16 Jan 13:03] *** You connected
[16 Jan 13:31] *** You disconnected
[16 Jan 14:42] +
[16 Jan 14:42] * jsmith wanders away...
[16 Jan 15:27] +
[16 Jan 15:27] * jsmith wanders away...
[16 Jan 15:37] *** You connected
[16 Jan 15:37] +stickster_work: I don't remember
[16 Jan 15:42] +stickster_work: Weren't there only six of us?
[16 Jan 15:42] +stickster_work: Three in each car, I think.
[16 Jan 15:45] Oh, then I got it right :-)
[16 Jan 15:45] That would explain why I can't even place another face
[16 Jan 15:51]