Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--configure.ac5
-rwxr-xr-xservices/console/console.py4
-rw-r--r--services/console/interface/Makefile.am2
-rw-r--r--services/console/interface/irc_client/Makefile.am5
-rw-r--r--services/console/interface/irc_client/__init__.py2
-rw-r--r--services/console/interface/irc_client/irc_client.py10
-rw-r--r--services/console/interface/network/network.py2
-rw-r--r--services/console/interface/xo/cpu.py1
-rw-r--r--services/console/lib/Makefile.am2
-rw-r--r--services/console/lib/gui/Makefile.am5
-rw-r--r--services/console/lib/gui/__init__.py0
-rw-r--r--services/console/lib/gui/treeview.py73
-rw-r--r--services/console/lib/purk/ABOUT7
-rw-r--r--services/console/lib/purk/COPYING340
-rw-r--r--services/console/lib/purk/Makefile.am17
-rw-r--r--services/console/lib/purk/README186
-rw-r--r--services/console/lib/purk/UrkLogQueryable.cs245
-rw-r--r--services/console/lib/purk/__init__.py94
-rw-r--r--services/console/lib/purk/conf.py86
-rw-r--r--services/console/lib/purk/events.py298
-rw-r--r--services/console/lib/purk/info.py8
-rw-r--r--services/console/lib/purk/irc.py328
-rw-r--r--services/console/lib/purk/parse_mirc.py457
-rw-r--r--services/console/lib/purk/scripts/Makefile.am16
-rwxr-xr-xservices/console/lib/purk/scripts/alias.py60
-rw-r--r--services/console/lib/purk/scripts/chaninfo.py320
-rw-r--r--services/console/lib/purk/scripts/clicks.py146
-rw-r--r--services/console/lib/purk/scripts/completion.py135
-rwxr-xr-xservices/console/lib/purk/scripts/console.py68
-rw-r--r--services/console/lib/purk/scripts/history.py45
-rwxr-xr-xservices/console/lib/purk/scripts/ignore.py43
-rw-r--r--services/console/lib/purk/scripts/irc_script.py588
-rw-r--r--services/console/lib/purk/scripts/keys.py70
-rw-r--r--services/console/lib/purk/scripts/theme.py366
-rwxr-xr-xservices/console/lib/purk/scripts/timeout.py45
-rw-r--r--services/console/lib/purk/scripts/ui_script.py132
-rw-r--r--services/console/lib/purk/servers.py51
-rw-r--r--services/console/lib/purk/ui.py105
-rw-r--r--services/console/lib/purk/urk_trace.py70
-rw-r--r--services/console/lib/purk/widgets.py811
-rw-r--r--services/console/lib/purk/windows.py298
41 files changed, 7 insertions, 5539 deletions
diff --git a/configure.ac b/configure.ac
index d61f24b..b7b348c 100644
--- a/configure.ac
+++ b/configure.ac
@@ -69,9 +69,7 @@ services/console/lib/Makefile
services/console/lib/graphics/Makefile
services/console/lib/procmem/Makefile
services/console/lib/net/Makefile
-services/console/lib/gui/Makefile
-services/console/lib/purk/Makefile
-services/console/lib/purk/scripts/Makefile
+services/console/lib/ui/Makefile
services/console/Makefile
services/console/interface/Makefile
services/console/interface/xo/Makefile
@@ -84,7 +82,6 @@ services/console/interface/memphis/Makefile
services/console/interface/network/Makefile
services/console/interface/logviewer/Makefile
services/console/interface/terminal/Makefile
-services/console/interface/irc_client/Makefile
sugar/Makefile
sugar/activity/Makefile
sugar/clipboard/Makefile
diff --git a/services/console/console.py b/services/console/console.py
index cf33a76..4fb3609 100755
--- a/services/console/console.py
+++ b/services/console/console.py
@@ -30,7 +30,7 @@ CONSOLE_BUS = 'org.laptop.sugar.Console'
CONSOLE_PATH = '/org/laptop/sugar/Console'
CONSOLE_IFACE = 'org.laptop.sugar.Console'
-class Console(object):
+class Console:
def __init__(self):
# Main Window
@@ -54,7 +54,6 @@ class Console(object):
self._load_interface('memphis', 'Memphis')
self._load_interface('logviewer', 'Log Viewer')
self._load_interface('terminal', 'Terminal')
- self._load_interface('irc_client', 'IRC')
self._load_interface('ps_watcher', 'Presence')
main_hbox = gtk.HBox()
@@ -91,4 +90,5 @@ bus = dbus.SessionBus()
name = dbus.service.BusName(CONSOLE_BUS, bus)
obj = Service(name)
+
gtk.main()
diff --git a/services/console/interface/Makefile.am b/services/console/interface/Makefile.am
index 628ab2c..ef0f3e4 100644
--- a/services/console/interface/Makefile.am
+++ b/services/console/interface/Makefile.am
@@ -1,4 +1,4 @@
-SUBDIRS = irc_client memphis network logviewer terminal xo
+SUBDIRS = memphis network logviewer terminal xo
sugardir = $(pkgdatadir)/services/console/interface
sugar_PYTHON = \
diff --git a/services/console/interface/irc_client/Makefile.am b/services/console/interface/irc_client/Makefile.am
deleted file mode 100644
index 934d9af..0000000
--- a/services/console/interface/irc_client/Makefile.am
+++ /dev/null
@@ -1,5 +0,0 @@
-sugardir = $(pkgdatadir)/services/console/interface/irc_client
-sugar_PYTHON = \
- __init__.py \
- irc_client.py
-
diff --git a/services/console/interface/irc_client/__init__.py b/services/console/interface/irc_client/__init__.py
deleted file mode 100644
index 5f8fa13..0000000
--- a/services/console/interface/irc_client/__init__.py
+++ /dev/null
@@ -1,2 +0,0 @@
-from irc_client import Interface
-
diff --git a/services/console/interface/irc_client/irc_client.py b/services/console/interface/irc_client/irc_client.py
deleted file mode 100644
index a718959..0000000
--- a/services/console/interface/irc_client/irc_client.py
+++ /dev/null
@@ -1,10 +0,0 @@
-import purk
-
-class Interface(object):
- def __init__(self):
- client = purk.Client()
- client.show()
- client.join_server('irc.freenode.net')
- self.widget = client.get_widget()
-
-
diff --git a/services/console/interface/network/network.py b/services/console/interface/network/network.py
index ecd09aa..1f22690 100644
--- a/services/console/interface/network/network.py
+++ b/services/console/interface/network/network.py
@@ -17,7 +17,7 @@
import gobject
from net.device import Device
-from gui.treeview import TreeView
+from ui.treeview import TreeView
class NetworkView(TreeView):
def __init__(self):
diff --git a/services/console/interface/xo/cpu.py b/services/console/interface/xo/cpu.py
index 30a2ca3..6f6a5a7 100644
--- a/services/console/interface/xo/cpu.py
+++ b/services/console/interface/xo/cpu.py
@@ -101,6 +101,7 @@ class XO_CPU(gtk.Frame):
gobject.timeout_add(self._DRW_CPU.frequency, self._update_cpu_usage)
def _update_cpu_usage(self):
+ print "update XO CPU"
self._cpu = self._DRW_CPU._get_CPU_usage()
self.set_label('System CPU Usage: ' + str(self._cpu) + '%')
diff --git a/services/console/lib/Makefile.am b/services/console/lib/Makefile.am
index 0201446..0d4dcce 100644
--- a/services/console/lib/Makefile.am
+++ b/services/console/lib/Makefile.am
@@ -1,4 +1,4 @@
-SUBDIRS = procmem graphics net gui purk
+SUBDIRS = procmem graphics net ui
sugardir = $(pkgdatadir)/shell/console/lib
sugar_PYTHON =
diff --git a/services/console/lib/gui/Makefile.am b/services/console/lib/gui/Makefile.am
deleted file mode 100644
index c045c9e..0000000
--- a/services/console/lib/gui/Makefile.am
+++ /dev/null
@@ -1,5 +0,0 @@
-sugardir = $(pkgdatadir)/services/console/lib/gui
-
-sugar_PYTHON = \
- __init__.py \
- treeview.py
diff --git a/services/console/lib/gui/__init__.py b/services/console/lib/gui/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/services/console/lib/gui/__init__.py
+++ /dev/null
diff --git a/services/console/lib/gui/treeview.py b/services/console/lib/gui/treeview.py
deleted file mode 100644
index 5f5dc96..0000000
--- a/services/console/lib/gui/treeview.py
+++ /dev/null
@@ -1,73 +0,0 @@
-# Copyright (C) 2007, Eduardo Silva <edsiper@gmail.com>
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2 of the License, or (at your option) any later version.
-#
-# This library 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
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the
-# Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-# Boston, MA 02111-1307, USA.
-
-import gtk
-
-class TreeView(gtk.ScrolledWindow):
- iters = [] # Iters index
-
- # Create a window with a treeview object
- #
- # cols = List of dicts, ex:
- #
- # cols = []
- # cols.append({'index': integer_index_position, 'name': string_col_name})
- def __init__(self, cols_def, cols_name):
- gtk.ScrolledWindow.__init__(self)
-
- self._iters = []
- self._treeview = gtk.TreeView()
-
- # Creating column data types
- self._store = gtk.TreeStore(*cols_def)
-
- # Columns definition
- cell = gtk.CellRendererText()
- tv_cols = []
-
- i=0
- for col in cols_name:
- col_tv = gtk.TreeViewColumn(col['name'], cell, text=i)
- col_tv.set_reorderable(True)
- col_tv.set_resizable(True)
- tv_cols.append(col_tv)
- i+=1
-
- # Setting treeview properties
- self._treeview.set_model(self._store)
- self._treeview.set_enable_search(True)
- self._treeview.set_rules_hint(True)
-
- for col in tv_cols:
- self._treeview.append_column(col)
- self.add(self._treeview)
-
- def add_row(self, cols_data):
- iter = self._store.insert_after(None, None)
- for col in cols_data:
- print col['index'],col['info']
- self._store.set_value(iter, int(col['index']) , col['info'])
-
- self.iters.append(iter)
- return iter
-
- def update_row(self, iter, cols_data):
- for col in cols_data:
- self._store.set_value(iter, int(col['index']) , str(col['info']))
-
- def remove_row(self, iter):
- self._store.remove(iter)
diff --git a/services/console/lib/purk/ABOUT b/services/console/lib/purk/ABOUT
deleted file mode 100644
index d1683db..0000000
--- a/services/console/lib/purk/ABOUT
+++ /dev/null
@@ -1,7 +0,0 @@
-Urk is a PyGTK IRC Client written by Vincent Povirk and Marc Liddell.
-This current version has been modified in order to have an PyGTK
-IRC Client Widget called 'Purk'.
-
-Suggestions are welcome...
-
-Eduardo Silva <edsiper@gmail.com>
diff --git a/services/console/lib/purk/COPYING b/services/console/lib/purk/COPYING
deleted file mode 100644
index 3912109..0000000
--- a/services/console/lib/purk/COPYING
+++ /dev/null
@@ -1,340 +0,0 @@
- GNU GENERAL PUBLIC LICENSE
- Version 2, June 1991
-
- Copyright (C) 1989, 1991 Free Software Foundation, Inc.
- 51 Franklin St, 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 Library 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.
-
- <one line to give the program's name and a brief idea of what it does.>
- Copyright (C) <year> <name of author>
-
- 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 St, 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 Library General
-Public License instead of this License.
diff --git a/services/console/lib/purk/Makefile.am b/services/console/lib/purk/Makefile.am
deleted file mode 100644
index 33fe595..0000000
--- a/services/console/lib/purk/Makefile.am
+++ /dev/null
@@ -1,17 +0,0 @@
-SUBDIRS = scripts
-sugardir = $(pkgdatadir)/services/console/lib/purk
-
-sugar_PYTHON = \
- __init__.py \
- conf.py \
- events.py \
- info.py \
- irc.py \
- parse_mirc.py \
- servers.py \
- ui.py \
- urk_trace.py \
- widgets.py \
- windows.py \
- README \
- ABOUT
diff --git a/services/console/lib/purk/README b/services/console/lib/purk/README
deleted file mode 100644
index 9e55cca..0000000
--- a/services/console/lib/purk/README
+++ /dev/null
@@ -1,186 +0,0 @@
-urk 0.-1.cvs
-http://urk.sourceforge.net/
-
-
-Overview:
-
-urk is an IRC client written purely in python for linux/gnome. It has a powerful
-built-in scripting system (also python), which is used to implement much of the
-client.
-
-
-Requirements/User installation:
-
-urk requires the following packages (and should run on any os that can provide
-them):
--python version 2.4 or greater (www.python.org)
--pygtk 2.6 or greater (www.pygtk.org)
-
-Most Linux (or at least GNOME) users should have these things already or be able
-to easily install them.
-
-Because urk is pure python, no compilation of urk is required. Just extract the
-source to somewhere and run 'python urk.py'.
-
-Windows versions of the above should theoretically work but may not in practice.
-I am hoping someone will come along and actually support urk on windows.
-
-
-Optional requirements:
-
-urk can also make use of these packages if you have them:
--pygtksourceview, part of gnome-python-extras <=2.12 and gnome-python-desktop
- >=2.14, for source highlighting and undo in the internal script editor
--python-dbus, for, well, not much (if dbus is available, urk only makes a single
- instance per session, and commands can be executed remotely by calling urk.py)
-
-
-Getting started:
-
-Make sure you have all the requirements, go to the directory where you have
-extracted the source, and type 'python urk.py'.
-
-We don't have any preferences windows yet. You can change your nickname by
-typing '/nick nickname' (replacing nickname with the nick you want to use)
-or typing a new nick in the nick field on the lower right corner and pressing
-enter.
-
-To connect, type '/server irc.gamesurge.net' (replacing irc.gamesurge.net with
-the server you want to connect to).
-
-If you want to connect to another server (without disconnecting the current
-one), use the -m switch as in '/server -m irc.gamesurge.net'.
-
-To join a channel when you're connected to a server, type '/join #channelname',
-replacing #channelname with the channel you want to join.
-
-urk currently only supports the bare minimum commands and features you should
-need to connect and chat normally. On channels, you can send messages by
-typing them (if you want to send a message that starts with a /, use /say to
-send your message). You can send actions to channels with /me and send messages
-to arbitrary targets with /msg. If urk does not recognize a command, it will
-send it to the server. This works to implement most commands you would expect
-on an irc client.
-
-
-Configuration:
-
-Most configuration has to be done manually. If urk is running, you can configure
-it using commands. The settings are stored in urk.conf on your profile
-directory, which you can locate by typing '/pyeval urk.userpath' in urk.
-
-To set a value in urk, type
-
-/pyexec conf.conf['setting'] = value
-
-To see the current value, type
-
-/pyeval conf.conf['setting']
-
-To unset a value (meaning urk will use the default), type
-
-/pyexec del conf.conf['setting']
-
-Setting: Description:
-
-'nick' The nickname urk should use. The default is to try to get
- it from the os. Put this in quotes when you set it.
-
-'altnicks' A list of alternative nicknames to use. The default is
- an empty list.
-
-'quitmsg' The message people see when you quit. The default is to
- advertise urk with your current version; we have to promote it somehow.
- This value needs to be in quotes.
-
-'autoreconnect' If True, urk will try to reconnect when you're
- disconnected from a network. Defaults to True. Set this to True or False.
-
-'highlight_words' A list of words, in addition to your nick, that cause a
- highlight event (normally the tab label turns blue and, if it's available,
- the tray icon shows up). For example: ['python', 'whale', 'peanut butter']
-
-'log_dir' The place where logs are written. The default is a
- directory called "logs" on your profile directory.
-
-'ui-gtk/tab-pos' The side of the window where the tabs will reside
- 2 for top
- 0 for left
- 1 for right
- 3 for bottom (default)
-
-'ui-gtk/show-menubar' If True, the menubar is shown. The default is True. Set
- this to True or False.
-
-'command_prefix' The prefix used to signal a command. Defaults to '/'
-
-'font' The font used for output. Defaults to "sans 8".
-
-'bg_color' The background color ("black" or "#000000").
-
-'fg_color' The foreground color ("white" or "#ffffff").
-
-'timestamp' A timestamp that will show up before messages. The
- default is no timestamp. A simple timestamp with hours and minutes is
- "[%H:%M] ". See http://docs.python.org/lib/module-time.html#l2h-1955 for
- a key to format this string.
-
-'start-console' If True, urk will start up with a special console window
- that shows debugging output (normally sent to a terminal) and accepts
- python expressions. Defaults to False.
-
-'status' If True, urk will be in status window mode. Each network
- will ALWAYS have a status window. When not in status window mode, networks
- only have a status window when there are no channel windows. Defaults to
- False.
-
-'open-file-command' The command used to open files and url's with your
- preferred application (such as "gnome-open"). This is ignored on Windows,
- and you should never need to mess with this, ever.
-
-
-System-wide installation:
-
-Not yet implemented.
-
-
-About scripting:
-
-urk scripts are python source files that contain definitions of functions with
-certain "magic" names, like onText (for when someone sends a channel or private
-message). See www.python.org for help on writing python code. The format for
-onText is:
-
-def onText(e):
- code
-
-e is an object used to pass on the various information relating to the event
-that triggered the function. The name is a convention we use, much like self.
-
-e.source is the nickname of the person who sent the message.
-
-e.target is the nickname or channel that received the message.
-
-e.text is the text of the message.
-
-e.network is an object representing the network where the message was sent.
-
-e.window is a window that seems to be related to the event for some unspecified
-reason. It could be the status window, a channel window, a query, anything.
-
-Complete documentation doesn't exist yet. Sorry. Ask us or look at the source. theme.py is good for finding event names.
-
-
-Bugs/Feedback:
-
-Naturally, feedback of any sort is welcome. Of course we want to know about
-bugs. In particular, we'd also like to hear about any features you want or
-expect in an irc client that urk doesn't have. While we'd like to limit the
-things that go in the default client (a notify list, for example, is something
-we'd want to see as an external script, not as part of the default setup, and
-something we're not likely to implement soon), there are probably a lot of
-little things that we may have skipped over because we don't use them or have
-become used to urk not having them.
-
-The best way to get in touch with us is by irc, at #urk on irc.gamesurge.net.
-Or send a message to the mailing list, urk-discussion@lists.sourceforge.net.
diff --git a/services/console/lib/purk/UrkLogQueryable.cs b/services/console/lib/purk/UrkLogQueryable.cs
deleted file mode 100644
index ee0611c..0000000
--- a/services/console/lib/purk/UrkLogQueryable.cs
+++ /dev/null
@@ -1,245 +0,0 @@
-using System;
-using System.Collections;
-using System.IO;
-using System.Text;
-using System.Threading;
-
-using Beagle.Daemon;
-using Beagle.Util;
-
-namespace Beagle.Daemon.UrkLogQueryable {
-
- [QueryableFlavor (Name="UrkLog", Domain=QueryDomain.Local, RequireInotify=false)]
- public class UrkLogQueryable : LuceneFileQueryable {
-
- private static Logger log = Logger.Get ("UrkLogQueryable");
-
- private string config_dir, log_dir, icons_dir;
-
- private int polling_interval_in_seconds = 60;
-
- //private GaimBuddyListReader list = new GaimBuddyListReader ();
-
- public UrkLogQueryable () : base ("UrkLogIndex")
- {
- config_dir = Path.Combine (PathFinder.HomeDir, ".urk");
- log_dir = Path.Combine (config_dir, "logs");
- icons_dir = Path.Combine (config_dir, "icons");
- }
-
- /////////////////////////////////////////////////
-
- private void StartWorker()
- {
- if (! Directory.Exists (log_dir)) {
- GLib.Timeout.Add (60000, new GLib.TimeoutHandler (CheckForExistence));
- return;
- }
-
- log.Info ("Starting urk log backend");
-
- Stopwatch stopwatch = new Stopwatch ();
- stopwatch.Start ();
-
- State = QueryableState.Crawling;
- Crawl ();
- State = QueryableState.Idle;
-
- if (!Inotify.Enabled) {
- Scheduler.Task task = Scheduler.TaskFromHook (new Scheduler.TaskHook (CrawlHook));
- task.Tag = "Crawling ~/.urk/logs to find new logfiles";
- task.Source = this;
- ThisScheduler.Add (task);
- }
-
- stopwatch.Stop ();
-
- log.Info ("urk log backend worker thread done in {0}", stopwatch);
- }
-
- public override void Start ()
- {
- base.Start ();
-
- ExceptionHandlingThread.Start (new ThreadStart (StartWorker));
- }
-
- /////////////////////////////////////////////////
-
- private void CrawlHook (Scheduler.Task task)
- {
- Crawl ();
- task.Reschedule = true;
- task.TriggerTime = DateTime.Now.AddSeconds (polling_interval_in_seconds);
- }
-
- private void Crawl ()
- {
- Inotify.Subscribe (log_dir, OnInotifyNewProtocol, Inotify.EventType.Create);
-
- // Walk through protocol subdirs
- foreach (string proto_dir in DirectoryWalker.GetDirectories (log_dir))
- CrawlProtocolDirectory (proto_dir);
- }
-
- private void CrawlNetworkDirectory (string proto_dir)
- {
- Inotify.Subscribe (proto_dir, OnInotifyNewTarget, Inotify.EventType.Create);
-
- // Walk through accounts
- foreach (string account_dir in DirectoryWalker.GetDirectories (proto_dir))
- CrawlTargetDirectory (account_dir);
- }
-
- private void CrawlTargetDirectory (string account_dir)
- {
- Inotify.Subscribe (account_dir, OnInotifyNewRemote, Inotify.EventType.Create);
-
- // Walk through remote user conversations
- foreach (string remote_dir in DirectoryWalker.GetDirectories (account_dir))
- CrawlRemoteDirectory (remote_dir);
- }
-
- private void CrawlRemoteDirectory (string remote_dir)
- {
- Inotify.Subscribe (remote_dir, OnInotifyNewConversation, Inotify.EventType.CloseWrite);
-
- foreach (FileInfo file in DirectoryWalker.GetFileInfos (remote_dir))
- if (FileIsInteresting (file.Name))
- IndexLog (file.FullName, Scheduler.Priority.Delayed);
- }
-
- /////////////////////////////////////////////////
-
- private bool CheckForExistence ()
- {
- if (!Directory.Exists (log_dir))
- return true;
-
- this.Start ();
-
- return false;
- }
-
- private bool FileIsInteresting (string filename)
- {
- // Filename must be fixed length, see below
- if (filename.Length < 21 || filename.Length > 22)
- return false;
-
- // Check match on regex: ^[0-9]{4}-[0-9]{2}-[0-9]{2}\\.[0-9]{6}\\.(txt|html)$
- // e.g. 2005-07-22.161521.txt
- // We'd use System.Text.RegularExpressions if they werent so much more expensive
- return Char.IsDigit (filename [0]) && Char.IsDigit (filename [1])
- && Char.IsDigit (filename [2]) && Char.IsDigit (filename [3])
- && filename [4] == '-'
- && Char.IsDigit (filename [5]) && Char.IsDigit (filename [6])
- && filename [7] == '-'
- && Char.IsDigit (filename [8]) && Char.IsDigit (filename [9])
- && filename [10] == '.'
- && Char.IsDigit (filename [11]) && Char.IsDigit (filename [12])
- && Char.IsDigit (filename [13]) && Char.IsDigit (filename [14])
- && Char.IsDigit (filename [15]) && Char.IsDigit (filename [16])
- && filename [17] == '.'
- && ( (filename [18] == 't' && filename [19] == 'x' && filename [20] == 't')
- || (filename [18] == 'h' && filename [19] == 't' && filename [20] == 'm' && filename [21] == 'l')
- );
- }
-
- /////////////////////////////////////////////////
-
- private void OnInotifyNewNetwork (Inotify.Watch watch,
- string path, string subitem, string srcpath,
- Inotify.EventType type)
- {
- if (subitem.Length == 0 || (type & Inotify.EventType.IsDirectory) == 0)
- return;
-
- CrawlNetworkDirectory (Path.Combine (path, subitem));
- }
-
- private void OnInotifyNewTarget (Inotify.Watch watch,
- string path, string subitem, string srcpath,
- Inotify.EventType type)
- {
- if (subitem.Length == 0 || (type & Inotify.EventType.IsDirectory) == 0)
- return;
-
- CrawlTargetDirectory (Path.Combine (path, subitem));
- }
-
- private void OnInotifyNewRemote (Inotify.Watch watch,
- string path, string subitem, string srcpath,
- Inotify.EventType type)
- {
- if (subitem.Length == 0 || (type & Inotify.EventType.IsDirectory) == 0)
- return;
-
- CrawlRemoteDirectory (Path.Combine (path, subitem));
- }
-
- private void OnInotifyNewConversation (Inotify.Watch watch,
- string path, string subitem, string srcpath,
- Inotify.EventType type)
- {
- if (subitem.Length == 0 || (type & Inotify.EventType.IsDirectory) != 0)
- return;
-
- if (FileIsInteresting (subitem))
- IndexLog (Path.Combine (path, subitem), Scheduler.Priority.Immediate);
- }
-
- /////////////////////////////////////////////////
-
- private static Indexable IRCLogToIndexable (string filename)
- {
- Uri uri = UriFu.PathToFileUri (filename);
- Indexable indexable = new Indexable (uri);
- indexable.ContentUri = uri;
- indexable.Timestamp = File.GetLastWriteTimeUtc (filename);
- indexable.MimeType = GaimLog.MimeType; // XXX
- indexable.HitType = "IRCLog";
- indexable.CacheContent = false;
-
- return indexable;
- }
-
- private void IndexLog (string filename, Scheduler.Priority priority)
- {
- if (! File.Exists (filename))
- return;
-
- if (IsUpToDate (filename))
- return;
-
- Indexable indexable = IRCLogToIndexable (filename);
- Scheduler.Task task = NewAddTask (indexable);
- task.Priority = priority;
- task.SubPriority = 0;
- ThisScheduler.Add (task);
- }
-
- override protected double RelevancyMultiplier (Hit hit)
- {
- return HalfLifeMultiplierFromProperty (hit, 0.25,
- "fixme:endtime", "fixme:starttime");
- }
-
- override protected bool HitFilter (Hit hit)
- {
- /*ImBuddy buddy = list.Search (hit ["fixme:speakingto"]);
-
- if (buddy != null) {
- if (buddy.Alias != "")
- hit ["fixme:speakingto_alias"] = buddy.Alias;
-
- //if (buddy.BuddyIconLocation != "")
- // hit ["fixme:speakingto_icon"] = Path.Combine (icons_dir, buddy.BuddyIconLocation);
- }*/
-
- return true;
- }
-
- }
-}
-
diff --git a/services/console/lib/purk/__init__.py b/services/console/lib/purk/__init__.py
deleted file mode 100644
index 35d93ad..0000000
--- a/services/console/lib/purk/__init__.py
+++ /dev/null
@@ -1,94 +0,0 @@
-import os
-import sys
-import traceback
-import events
-import windows
-
-urkpath = os.path.abspath(os.path.dirname(__file__))
-
-if os.path.abspath(os.curdir) != os.path.join(urkpath):
- sys.path[0] = os.path.join(urkpath)
-
-sys.path = [
- os.path.join(urkpath, "scripts"),
- ] + sys.path
-
-script_path = urkpath+"/scripts"
-
-from ui import *
-
-# Here I'm trying to handle the original URL IRC Client, urk don't use
-# normal classes . Let's try to get a urk widget:
-class Trigger(object):
- def __init__(self):
- self._mods = []
- self.events = events
- self._load_scripts()
-
- def _load_scripts(self):
- script_path = urkpath + "/scripts"
- try:
- suffix = os.extsep+"py"
- for script in os.listdir(script_path):
- if script.endswith(suffix):
- try:
- mod = self.events.load(script)
- self._mods.append(mod)
- except:
- traceback.print_exc()
- print "Failed loading script %s." % script
- except OSError:
- pass
-
- def get_modules(self):
- return self._mods
-
-class Core(object):
- def __init__(self):
- self.window = None
- self.trigger = Trigger()
- self.events = self.trigger.events
- self.manager = widgets.UrkUITabs(self)
-
- mods = self.trigger.get_modules()
- for m in mods:
- m.core = self
- m.manager = self.manager
-
- if not self.window:
- self.window = windows.new(windows.StatusWindow, irc.Network(self), "status", self)
- self.window.activate()
-
- register_idle(self.trigger_start)
- gtk.gdk.threads_enter()
-
- def run_command(self, command):
- offset = 0
- if command[0] == '/':
- offset = 1
-
- self.events.run(command[offset:], self.manager.get_active(), self.window.network)
-
- def trigger_start(self):
- self.events.trigger("Start")
-
- def _add_script(self, module):
- return
-
-class Client(object):
- def __init__(self):
- self.core = Core()
- self.widget = self.core.manager.box
- def run_command(self, command):
- self.core.run_command(command)
-
- def join_server(self, network_name, port=6667):
- command = 'server '+ network_name + ' ' + str(port)
- self.run_command(command)
-
- def get_widget(self):
- return self.widget
-
- def show(self):
- self.widget.show_all()
-
diff --git a/services/console/lib/purk/conf.py b/services/console/lib/purk/conf.py
deleted file mode 100644
index 9cae512..0000000
--- a/services/console/lib/purk/conf.py
+++ /dev/null
@@ -1,86 +0,0 @@
-import os
-urkpath = os.path.dirname(__file__)
-
-def path(filename=""):
- if filename:
- return os.path.join(urkpath, filename)
- else:
- return urkpath
-
-if os.access(path('profile'),os.F_OK) or os.path.expanduser("~") == "~":
- userpath = path('profile')
- if not os.access(userpath,os.F_OK):
- os.mkdir(userpath)
- if not os.access(os.path.join(userpath,'scripts'),os.F_OK):
- os.mkdir(os.path.join(userpath,'scripts'))
-else:
- userpath = os.path.join(os.path.expanduser("~"), ".urk")
- if not os.access(userpath,os.F_OK):
- os.mkdir(userpath, 0700)
- if not os.access(os.path.join(userpath,'scripts'),os.F_OK):
- os.mkdir(os.path.join(userpath,'scripts'), 0700)
-
-CONF_FILE = os.path.join(userpath,'urk.conf')
-
-
-def pprint(obj, depth=-2):
- depth += 2
-
- string = []
-
- if isinstance(obj, dict):
- if obj:
- string.append('{\n')
-
- for key in obj:
- string.append('%s%s%s' % (' '*depth, repr(key), ': '))
- string += pprint(obj[key], depth)
-
- string.append('%s%s' % (' '*depth, '},\n'))
-
- else:
- string.append('{},\n')
-
- elif isinstance(obj, list):
- if obj:
- string.append('[\n')
-
- for item in obj:
- string.append('%s' % (' '*depth))
- string += pprint(item, depth)
-
- string.append('%s%s' % (' '*depth, '],\n'))
-
- else:
- string.append('[],\n')
-
- else:
- string.append('%s,\n' % (repr(obj),))
-
- if depth:
- return string
- else:
- return ''.join(string)[:-2]
-
-def save(*args):
- new_file = not os.access(CONF_FILE,os.F_OK)
- fd = file(CONF_FILE, "wb")
- try:
- if new_file:
- os.chmod(CONF_FILE,0600)
- fd.write(pprint(conf))
- finally:
- fd.close()
-
-#events.register('Exit', 'post', save)
-
-try:
- conf = eval(file(CONF_FILE, "U").read().strip())
-except IOError, e:
- if e.args[0] == 2:
- conf = {}
- else:
- raise
-
-if __name__ == '__main__':
- print pprint(conf)
diff --git a/services/console/lib/purk/events.py b/services/console/lib/purk/events.py
deleted file mode 100644
index 2a0d45e..0000000
--- a/services/console/lib/purk/events.py
+++ /dev/null
@@ -1,298 +0,0 @@
-import sys
-import os
-import traceback
-
-pyending = os.extsep + 'py'
-
-class error(Exception):
- pass
-
-class EventStopError(error):
- pass
-
-class CommandError(error):
- pass
-
-class data(object):
- done = False
- quiet = False
-
- def __init__(self, **kwargs):
- for attr in kwargs.items():
- setattr(self, *attr)
-
-trigger_sequence = ("pre", "setup", "on", "setdown", "post")
-
-all_events = {}
-loaded = {}
-
-# An event has occurred, the e_name event!
-def trigger(e_name, e_data=None, **kwargs):
- if e_data is None:
- e_data = data(**kwargs)
-
- #print 'Event:', e_name, e_data
-
- failure = True
- error = None
-
- if e_name in all_events:
- for e_stage in trigger_sequence:
- if e_stage in all_events[e_name]:
- for f_ref, s_name in all_events[e_name][e_stage]:
- try:
- f_ref(e_data)
- except EventStopError:
- return
- except CommandError, e:
- error = e.args
- continue
- except:
- traceback.print_exc()
- failure = False
- if failure:
- print "Error handling: " + e_name
-
- return error
-
-# Stop all processing of the current event now!
-def halt():
- raise EventStopError
-
-# Registers a specific function with an event at the given sequence stage.
-def register(e_name, e_stage, f_ref, s_name=""):
- global all_events
-
- if e_name not in all_events:
- all_events[e_name] = {}
-
- if e_stage not in all_events[e_name]:
- all_events[e_name][e_stage] = []
-
- all_events[e_name][e_stage] += [(f_ref, s_name)]
-
-# turn a filename (or module name) and trim it to the name of the module
-def get_scriptname(name):
- s_name = os.path.basename(name)
- if s_name.endswith(pyending):
- s_name = s_name[:-len(pyending)]
- return s_name
-
-#take a given script name and turn it into a filename
-def get_filename(name):
- # split the directory and filename
- dirname = os.path.dirname(name)
- s_name = get_scriptname(name)
-
- for path in dirname and (dirname,) or sys.path:
- filename = os.path.join(path, s_name + pyending)
- if os.access(filename, os.R_OK):
- return filename
-
- raise ImportError("No urk script %s found" % name)
-
-# register the events defined by obj
-def register_all(name, obj):
- # we look through everything defined in the file
- for f in dir(obj):
- # for each bit of the event sequence
- for e_stage in trigger_sequence:
-
- # if the function is for this bit
- if f.startswith(e_stage):
- # get a reference to a function
- f_ref = getattr(obj, f)
- #print f
- # normalise to the event name
- e_name = f.replace(e_stage, "", 1)
-
- # add our function to the right event section
- register(e_name, e_stage, f_ref, name)
-
- break
-
-#load a .py file into a new module object without affecting sys.modules
-def load_pyfile(filename):
- s_name = get_scriptname(filename)
- return __import__(s_name)
-
-# Load a python script and register
-# the functions defined in it for events.
-# Return True if we loaded the script, False if it was already loaded
-def load(name):
- s_name = get_scriptname(name)
- filename = get_filename(name)
-
- if s_name in loaded:
- return False
-
- loaded[s_name] = None
-
- try:
- module = load_pyfile(filename)
- loaded[s_name] = module
- except:
- del loaded[s_name]
- raise
-
- register_all(s_name, loaded[s_name])
-
- return module
-
-# Is the script with the given name loaded?
-def is_loaded(name):
- return get_scriptname(name) in loaded
-
-# Remove any function which was defined in the given script
-def unload(name):
- s_name = get_scriptname(name)
-
- del loaded[s_name]
-
- for e_name in list(all_events):
- for e_stage in list(all_events[e_name]):
- to_check = all_events[e_name][e_stage]
-
- all_events[e_name][e_stage] = [(f, m) for f, m in to_check if m != s_name]
-
- if not all_events[e_name][e_stage]:
- del all_events[e_name][e_stage]
-
- if not all_events[e_name]:
- del all_events[e_name]
-
-def reload(name):
- s_name = get_scriptname(name)
-
- if s_name not in loaded:
- return False
-
- temp = loaded[s_name]
-
- unload(s_name)
-
- try:
- load(name)
- return True
- except:
- loaded[s_name] = temp
- register_all(s_name, temp)
- raise
-
-def run(text, window, network):
- split = text.split(' ')
-
- c_data = data(name=split.pop(0), text=text, window=window, network=network)
-
- if split and split[0].startswith('-'):
- c_data.switches = set(split.pop(0)[1:])
- else:
- c_data.switches = set()
-
- c_data.args = split
-
- event_name = "Command" + c_data.name.capitalize()
- #print "searching: " + event_name
- #for s in all_events:
- # print "match: " + s
- # if s == event_name:
- # print "we got it!"
-
- if event_name in all_events:
- result = trigger(event_name, c_data)
-
- if result:
- print "* /%s: %s" % (c_data.name, result[0])
- c_data.window.write("* /%s: %s" % (c_data.name, result[0]))
- else:
- trigger("Command", c_data)
-
- if not c_data.done:
- c_data.window.write("* /%s: No such command exists" % (c_data.name))
-
-def onCommandPyeval(e):
- loc = sys.modules.copy()
- loc.update(e.__dict__)
- import pydoc #fix nonresponsive help() command
- old_pager, pydoc.pager = pydoc.pager, pydoc.plainpager
- try:
- result = repr(eval(' '.join(e.args), loc))
- if 's' in e.switches:
- run(
- 'say - %s => %s' % (' '.join(e.args),result),
- e.window,
- e.network
- )
- else:
- e.window.write(result)
- except:
- for line in traceback.format_exc().split('\n'):
- e.window.write(line)
- pydoc.pager = old_pager
-
-def onCommandPyexec(e):
- loc = sys.modules.copy()
- loc.update(e.__dict__)
- import pydoc #fix nonresponsive help() command
- old_pager, pydoc.pager = pydoc.pager, pydoc.plainpager
- try:
- exec ' '.join(e.args) in loc
- except:
- for line in traceback.format_exc().split('\n'):
- e.window.write(line)
- pydoc.pager = old_pager
-
-def onCommandLoad(e):
- if e.args:
- name = e.args[0]
- else:
- e.window.write('Usage: /load scriptname')
-
- try:
- if load(name):
- e.window.write("* The script '%s' has been loaded." % name)
- else:
- raise CommandError("The script is already loaded; use /reload instead")
- except:
- e.window.write(traceback.format_exc(), line_ending='')
- raise CommandError("Error loading the script")
-
-def onCommandUnload(e):
- if e.args:
- name = e.args[0]
- else:
- e.window.write('Usage: /unload scriptname')
-
- if is_loaded(name):
- unload(name)
- e.window.write("* The script '%s' has been unloaded." % name)
- else:
- raise CommandError("No such script is loaded")
-
-def onCommandReload(e):
- if e.args:
- name = e.args[0]
- else:
- e.window.write('Usage: /reload scriptname')
-
- try:
- if reload(name):
- e.window.write("* The script '%s' has been reloaded." % name)
- else:
- raise CommandError("The script isn't loaded yet; use /load instead")
- except:
- e.window.write(traceback.format_exc(), line_ending='')
-
-def onCommandScripts(e):
- e.window.write("Loaded scripts:")
- for name in loaded:
- e.window.write("* %s" % name)
-
-def onCommandEcho(e):
- e.window.write(' '.join(e.args))
-
-name = ''
-for name in globals():
- if name.startswith('onCommand'):
- register(name[2:], "on", globals()[name], '_all_events')
-del name
diff --git a/services/console/lib/purk/info.py b/services/console/lib/purk/info.py
deleted file mode 100644
index 3765845..0000000
--- a/services/console/lib/purk/info.py
+++ /dev/null
@@ -1,8 +0,0 @@
-name = "PUrk"
-long_name = "Purk IRC"
-version = 0, 1, "git"
-long_version = "%s v%s" % (long_name, ".".join(str(x) for x in version))
-website = "http://dev.laptop.org/"
-authors = ["Vincent Povirk", "Marc Liddell"]
-copyright = "2005 %s" % ', '.join(authors)
-
diff --git a/services/console/lib/purk/irc.py b/services/console/lib/purk/irc.py
deleted file mode 100644
index d5a01aa..0000000
--- a/services/console/lib/purk/irc.py
+++ /dev/null
@@ -1,328 +0,0 @@
-import socket
-import sys
-
-from conf import conf
-import ui
-import windows
-import info
-
-DISCONNECTED = 0
-CONNECTING = 1
-INITIALIZING = 2
-CONNECTED = 3
-
-def parse_irc(msg, server):
- msg = msg.split(' ')
-
- # if our very first character is :
- # then this is the source,
- # otherwise insert the server as the source
- if msg and msg[0].startswith(':'):
- msg[0] = msg[0][1:]
- else:
- msg.insert(0, server)
-
- # loop through the msg until we find
- # something beginning with :
- for i, token in enumerate(msg):
- if token.startswith(':'):
- # remove the :
- msg[i] = msg[i][1:]
-
- # join up the rest
- msg[i:] = [' '.join(msg[i:])]
- break
-
- # filter out the empty pre-":" tokens and add on the text to the end
- return [m for m in msg[:-1] if m] + msg[-1:]
-
- # note: this sucks and makes very little sense, but it matches the BNF
- # as far as we've tested, which seems to be the goal
-
-def default_nicks():
- try:
- nicks = [conf.get('nick')] + conf.get('altnicks',[])
- if not nicks[0]:
- import getpass
- nicks = [getpass.getuser()]
- except:
- nicks = ["mrurk"]
- return nicks
-
-class Network(object):
- socket = None
-
- def __init__(self, core, server="irc.default.org", port=6667, nicks=[],
- username="", fullname="", name=None, **kwargs):
- self.manager = core.manager
- self.server = server
- self.port = port
- self.events = core.events
-
- self.name = name or server
-
- self.nicks = nicks or default_nicks()
- self.me = self.nicks[0]
-
- self.username = username or "urk"
- self.fullname = fullname or conf.get("fullname", self.username)
- self.password = ''
-
- self.isupport = {
- 'NETWORK': server,
- 'PREFIX': '(ohv)@%+',
- 'CHANMODES': 'b,k,l,imnpstr',
- }
- self.prefixes = {'o':'@', 'h':'%', 'v':'+', '@':'o', '%':'h', '+':'v'}
-
- self.status = DISCONNECTED
- self.failedhosts = [] #hosts we've tried and failed to connect to
- self.channel_prefixes = '&#+$' # from rfc2812
-
- self.on_channels = set()
- self.requested_joins = set()
- self.requested_parts = set()
-
- self.buffer = ''
-
- #called when we get a result from the dns lookup
- def on_dns(self, result, error):
- if error:
- self.disconnect(error=error[1])
- else:
- #import os
- #import random
- #random.seed()
- #random.shuffle(result)
- if socket.has_ipv6: #prefer ipv6
- result = [(f, t, p, c, a) for (f, t, p, c, a) in result if f == socket.AF_INET6]+result
- elif hasattr(socket,"AF_INET6"): #ignore ipv6
- result = [(f, t, p, c, a) for (f, t, p, c, a) in result if f != socket.AF_INET6]
-
- self.failedlasthost = False
-
- for f, t, p, c, a in result:
- if (f, t, p, c, a) not in self.failedhosts:
- try:
- self.socket = socket.socket(f, t, p)
- except:
- continue
- self.source = ui.fork(self.on_connect, self.socket.connect, a)
- self.failedhosts.append((f, t, p, c, a))
- if set(self.failedhosts) >= set(result):
- self.failedlasthost = True
- break
- else:
- self.failedlasthost = True
- if len(result):
- self.failedhosts[:] = (f, t, p, c, a),
- f, t, p, c, a = result[0]
- try:
- self.socket = socket.socket(f, t, p)
- self.source = ui.fork(self.on_connect, self.socket.connect, a)
- except:
- self.disconnect(error="Couldn't find a host we can connect to")
- else:
- self.disconnect(error="Couldn't find a host we can connect to")
-
- #called when socket.open() returns
- def on_connect(self, result, error):
- if error:
- self.disconnect(error=error[1])
- #we should immediately retry if we failed to open the socket and there are hosts left
- if self.status == DISCONNECTED and not self.failedlasthost:
- windows.get_default(self).write("* Retrying with next available host")
- self.connect()
- else:
- self.source = source = ui.Source()
- self.status = INITIALIZING
- self.failedhosts[:] = ()
-
- self.events.trigger('SocketConnect', network=self)
-
- if source.enabled:
- self.source = ui.fork(self.on_read, self.socket.recv, 8192)
-
- #called when we read data or failed to read data
- def on_read(self, result, error):
- if error:
- self.disconnect(error=error[1])
- elif not result:
- self.disconnect(error="Connection closed by remote host")
- else:
- self.source = source = ui.Source()
-
- self.buffer = (self.buffer + result).split("\r\n")
-
- for line in self.buffer[:-1]:
- self.got_msg(line)
-
- if self.buffer:
- self.buffer = self.buffer[-1]
- else:
- self.buffer = ''
-
- if source.enabled:
- self.source = ui.fork(self.on_read, self.socket.recv, 8192)
-
- def raw(self, msg):
- self.events.trigger("OwnRaw", network=self, raw=msg)
-
- if self.status >= INITIALIZING:
- self.socket.send(msg + "\r\n")
-
- def got_msg(self, msg):
- pmsg = parse_irc(msg, self.server)
-
- e_data = self.events.data(
- raw=msg,
- msg=pmsg,
- text=pmsg[-1],
- network=self,
- window=windows.get_default(self, self.manager)
- )
-
- if "!" in pmsg[0]:
- e_data.source, e_data.address = pmsg[0].split('!',1)
-
- else:
- e_data.source, e_data.address = pmsg[0], ''
-
- if len(pmsg) > 2:
- e_data.target = pmsg[2]
- else:
- e_data.target = pmsg[-1]
-
- self.events.trigger('Raw', e_data)
-
- def connect(self):
- if not self.status:
- self.status = CONNECTING
-
- self.source = ui.fork(self.on_dns, socket.getaddrinfo, self.server, self.port, 0, socket.SOCK_STREAM)
-
- self.events.trigger('Connecting', network=self)
-
- def disconnect(self, error=None):
- if self.socket:
- self.socket.close()
-
- if self.source:
- self.source.unregister()
- self.source = None
-
- self.socket = None
-
- self.status = DISCONNECTED
-
- #note: connecting from onDisconnect is probably a Bad Thing
- self.events.trigger('Disconnect', network=self, error=error)
-
- #trigger a nick change if the nick we want is different from the one we
- # had.
- if self.me != self.nicks[0]:
- self.events.trigger(
- 'Nick', network=self, window=windows.get_default(self),
- source=self.me, target=self.nicks[0], address='',
- text=self.nicks[0]
- )
- self.me = self.nicks[0]
-
- def norm_case(self, string):
- return string.lower()
-
- def quit(self, msg=None):
- if self.status:
- try:
- if msg == None:
- msg = conf.get('quitmsg', "%s - %s" % (info.long_version, info.website))
- self.raw("QUIT :%s" % msg)
- except:
- pass
- self.disconnect()
-
- def join(self, target, key='', requested=True):
- if key:
- key = ' '+key
- self.raw("JOIN %s%s" % (target,key))
- if requested:
- for chan in target.split(' ',1)[0].split(','):
- if chan == '0':
- self.requested_parts.update(self.on_channels)
- else:
- self.requested_joins.add(self.norm_case(chan))
-
- def part(self, target, msg="", requested=True):
- if msg:
- msg = " :" + msg
-
- self.raw("PART %s%s" % (target, msg))
- if requested:
- for chan in target.split(' ',1)[0].split(','):
- self.requested_parts.add(self.norm_case(target))
-
- def msg(self, target, msg):
- self.raw("PRIVMSG %s :%s" % (target, msg))
-
- self.events.trigger(
- 'OwnText', source=self.me, target=str(target), text=msg,
- network=self, window=windows.get_default(self, self.manager)
- )
-
- def notice(self, target, msg):
- self.raw("NOTICE %s :%s" % (target, msg))
-
- self.events.trigger(
- 'OwnNotice', source=self.me, target=str(target), text=msg,
- network=self, window=windows.get_default(self)
- )
-
-#a Network that is never connected
-class DummyNetwork(Network):
- def __nonzero__(self):
- return False
-
- def __init__(self, core):
- Network.__init__(self, core)
-
- self.name = self.server = self.isupport['NETWORK'] = "None"
-
- def connect(self):
- raise NotImplementedError, "Cannot connect dummy network."
-
- def raw(self, msg):
- raise NotImplementedError, "Cannot send %s over the dummy network." % repr(msg)
-
-#dummy_network = DummyNetwork()
-
-#this was ported from srvx's tools.c
-def match_glob(text, glob, t=0, g=0):
- while g < len(glob):
- if glob[g] in '?*':
- star_p = q_cnt = 0
- while g < len(glob):
- if glob[g] == '*':
- star_p = True
- elif glob[g] == '?':
- q_cnt += 1
- else:
- break
- g += 1
- t += q_cnt
- if t > len(text):
- return False
- if star_p:
- if g == len(glob):
- return True
- for i in xrange(t, len(text)):
- if text[i] == glob[g] and match_glob(text, glob, i+1, g+1):
- return True
- return False
- else:
- if t == len(text) and g == len(glob):
- return True
- if t == len(text) or g == len(glob) or text[t] != glob[g]:
- return False
- t += 1
- g += 1
- return t == len(text)
diff --git a/services/console/lib/purk/parse_mirc.py b/services/console/lib/purk/parse_mirc.py
deleted file mode 100644
index 186ff9b..0000000
--- a/services/console/lib/purk/parse_mirc.py
+++ /dev/null
@@ -1,457 +0,0 @@
-try:
- from conf import conf
-except ImportError:
- conf = {}
-
-BOLD = '\x02'
-UNDERLINE = '\x1F'
-MIRC_COLOR = '\x03'
-MIRC_COLOR_BG = MIRC_COLOR, MIRC_COLOR
-BERS_COLOR = '\x04'
-RESET = '\x0F'
-
-colors = (
- '#FFFFFF', '#000000', '#00007F', '#009300',
- '#FF0000', '#7F0000', '#9C009C', '#FF7F00',
- '#FFFF00', '#00FF00', '#009393', '#00FFFF',
- '#0000FF', '#FF00FF', '#7F7F7F', '#D2D2D2'
- )
-
-def get_mirc_color(number):
- if number == '99':
- return None
-
- number = int(number) & 15
-
- confcolors = conf.get('colors', colors)
- try:
- return confcolors[number]
- except:
- # someone edited their colors wrongly
- return colors[number]
-
-DEC_DIGITS, HEX_DIGITS = set('0123456789'), set('0123456789abcdefABCDEF')
-
-def parse_mirc_color(string, pos, open_tags, tags):
- color_chars = 1
-
- if MIRC_COLOR in open_tags:
- fgtag = open_tags.pop(MIRC_COLOR)
- fgtag['to'] = pos
- tags.append(fgtag)
-
- if MIRC_COLOR_BG in open_tags:
- bgtag = open_tags.pop(MIRC_COLOR_BG)
- bgtag['to'] = pos
- tags.append(bgtag)
-
- bg = bgtag['data'][1]
- else:
- bg = None
-
- if string[0] in DEC_DIGITS:
- if string[1] in DEC_DIGITS:
- fg = get_mirc_color(string[:2])
- string = string[1:]
- color_chars += 2
-
- else:
- fg = get_mirc_color(string[0])
- color_chars += 1
-
- if string[1] == "," and string[2] in DEC_DIGITS:
- if string[3] in DEC_DIGITS:
- bg = get_mirc_color(string[2:4])
- color_chars += 3
-
- else:
- bg = get_mirc_color(string[2])
- color_chars += 2
-
- else:
- fg = bg = None
-
- if fg:
- open_tags[MIRC_COLOR] = {'data': ("foreground",fg), 'from': pos}
- else:
- open_tags.pop(MIRC_COLOR,None)
-
- if bg:
- open_tags[MIRC_COLOR_BG] = {'data': ("background",bg), 'from': pos}
- else:
- open_tags.pop(MIRC_COLOR_BG,None)
-
- return color_chars
-
-def parse_bersirc_color(string, pos, open_tags, tags):
- bg = None
- if MIRC_COLOR in open_tags:
- tag = open_tags.pop(MIRC_COLOR)
- tag['to'] = pos
- tags.append(tag)
-
- if MIRC_COLOR_BG in open_tags:
- bgtag = open_tags.pop(MIRC_COLOR_BG)
- bgtag['to'] = pos
- tags.append(bgtag)
-
- bg = bgtag['data'][1]
-
- for c in (0, 1, 2, 3, 4, 5):
- if string[c] not in HEX_DIGITS:
- return 1
- fg = '#' + string[:6].upper()
-
- color_chars = 7
- for c in (7, 8, 9, 10, 11, 12):
- if string[c] not in HEX_DIGITS:
- break
- else:
- if string[6] == ",":
- bg = '#' + string[7:13].upper()
- color_chars = 14
-
- if fg:
- open_tags[MIRC_COLOR] = {'data': ("foreground",fg), 'from': pos}
- else:
- open_tags.pop(MIRC_COLOR,None)
-
- if bg:
- open_tags[MIRC_COLOR_BG] = {'data': ("background",bg), 'from': pos}
- else:
- open_tags.pop(MIRC_COLOR_BG,None)
-
- return color_chars
-
-def parse_bold(string, pos, open_tags, tags):
- if BOLD in open_tags:
- tag = open_tags.pop(BOLD)
- tag['to'] = pos
- tags.append(tag)
-
- else:
- open_tags[BOLD] = {'data': ('weight', BOLD), 'from': pos}
-
- return 1
-
-def parse_underline(string, pos, open_tags, tags):
- if UNDERLINE in open_tags:
- tag = open_tags.pop(UNDERLINE)
- tag['to'] = pos
- tags.append(tag)
-
- else:
- open_tags[UNDERLINE] = {'data': ('underline', UNDERLINE), 'from': pos}
-
- return 1
-
-def parse_reset(string, pos, open_tags, tags):
- for t in open_tags:
- tag = open_tags[t]
- tag['to'] = pos
- tags.append(tag)
-
- open_tags.clear()
-
- return 1
-
-tag_parser = {
- MIRC_COLOR: parse_mirc_color,
- BERS_COLOR: parse_bersirc_color,
- BOLD: parse_bold,
- UNDERLINE: parse_underline,
- RESET: parse_reset
- }
-
-def parse_mirc(string):
- string += RESET
-
- out = ''
- open_tags = {}
- tags = []
- text_i = outtext_i = 0
-
- for tag_i, char in enumerate(string):
- if char in tag_parser:
- out += string[text_i:tag_i]
-
- outtext_i += tag_i - text_i
-
- text_i = tag_i + tag_parser[char](
- string[tag_i+1:],
- outtext_i,
- open_tags,
- tags
- )
-
- return tags, out
-
-#transforms for unparse_mirc
-
-#^O
-def transform_reset(start, end):
- return RESET, '', {}
-
-#^K
-def transform_color_reset(start, end):
- if ('foreground' in start and 'foreground' not in end) or \
- ('background' in start and 'background' not in end):
- result = start.copy()
- result.pop("foreground",None)
- result.pop("background",None)
- return MIRC_COLOR, DEC_DIGITS, result
- else:
- return '','',start
-
-#^KXX
-def transform_color(start, end):
- if (start.get('foreground',99) != end.get('foreground',99)):
- confcolors = conf.get('colors', colors)
- result = start.copy()
- if 'foreground' in end:
- try:
- index = list(confcolors).index(end['foreground'].upper())
- except ValueError:
- return '','',start
- result['foreground'] = end['foreground']
- else:
- index = 99
- del result['foreground']
- return '\x03%02i' % index, ',', result
- else:
- return '','',start
-
-#^KXX,YY
-def transform_bcolor(start, end):
- if (start.get('background',99) != end.get('background',99)):
- confcolors = conf.get('colors', colors)
- result = start.copy()
- if 'foreground' in end:
- try:
- fg_index = list(confcolors).index(end['foreground'].upper())
- except ValueError:
- return '','',start
- result['foreground'] = end['foreground']
- else:
- fg_index = 99
- result.pop('foreground',None)
- if 'background' in end:
- try:
- bg_index = list(confcolors).index(end['background'].upper())
- except ValueError:
- return '','',start
- result['background'] = end['background']
- else:
- bg_index = 99
- del result['background']
- return '\x03%02i,%02i' % (fg_index, bg_index), ',', result
- else:
- return '','',start
-
-#^LXXXXXX
-def transform_bersirc(start, end):
- if 'foreground' in end and end['foreground'] != start.get('foreground'):
- result = start.copy()
- result['foreground'] = end['foreground']
- return "\x04%s" % end['foreground'][1:], ',', result
- else:
- return '','',start
-
-#^LXXXXXX,YYYYYY
-def transform_bbersirc(start, end):
- if 'foreground' in end and 'background' in end and (
- end['foreground'] != start.get('foreground') or
- end['background'] != start.get('background')):
- result = start.copy()
- result['foreground'] = end['foreground']
- result['background'] = end['background']
- return "\x04%s,%s" % (end['foreground'][1:], end['background'][1:]), ',', result
- else:
- return '','',start
-
-
-#^B
-def transform_underline(start, end):
- if ('underline' in start) != ('underline' in end):
- result = start.copy()
- if 'underline' in start:
- del result['underline']
- else:
- result['underline'] = UNDERLINE
- return UNDERLINE, '', result
- else:
- return '','',start
-
-#^U
-def transform_bold(start, end):
- if ('weight' in start) != ('weight' in end):
- result = start.copy()
- if 'weight' in start:
- del result['weight']
- else:
- result['weight'] = BOLD
- return BOLD, '', result
- else:
- return '','',start
-
-#^B^B
-#In some rare circumstances, we HAVE to do this to generate a working string
-def transform_dbold(start, end):
- return BOLD*2, '', start
-
-#return the formatting needed to transform one set of format tags to another
-def transform(start, end, nextchar=" "):
- transform_functions = (
- transform_reset, transform_color_reset, transform_color, transform_bcolor,
- transform_bersirc, transform_bbersirc, transform_underline,
- transform_bold, transform_dbold,
- )
-
- candidates = [('','',start)]
- result = None
-
- for f in transform_functions:
- for string, badchars, s in candidates[:]:
- newstring, badchars, s = f(s, end)
- string += newstring
- if newstring and (result == None or len(string) < len(result)):
- if nextchar not in badchars and s == end:
- result = string
- else:
- candidates.append((string, badchars, s))
- return result
-
-def unparse_mirc(tagsandtext):
- lasttags, lastchar = {}, ''
-
- string = []
- for tags, char in tagsandtext:
- if tags != lasttags:
- string.append(transform(lasttags, tags, char[0]))
- string.append(char)
- lasttags, lastchar = tags, char
- return ''.join(string)
-
-if __name__ == "__main__":
- tests = [
- 'not\x02bold\x02not',
- 'not\x1Funderline\x1Fnot',
-
- "\x02\x1FHi\x0F",
-
- 'not\x030,17white-on-black\x0304red-on-black\x03nothing',
-
- "\x040000CC<\x04nick\x040000CC>\x04 text",
-
- '\x04770077,FFFFFFbersirc color with background! \x04000077setting foreground! \x04reset!',
-
- '\x047700,FFFFbersirc',
-
- "\x03123Hello",
-
- "\x0312,Hello",
-
- "\x034Hello",
-
- "Bo\x02ld",
-
- "\x034,5Hello\x036Goodbye",
-
- "\x04ff0000,00ff00Hello\x040000ffGoodbye",
-
- "\x04777777(\x0400CCCCstuff\x04777777)\x04",
-
- '\x0307orange\x04CCCCCCgrey\x0307orange',
-
- '\x04CCCCCC,444444sdf\x0304jkl',
-
- '\x0403\x02\x02,trixy',
-
- '\x04FFFFFF\x02\x02,000000trixy for bersirc',
- ]
-
- results = [
- ([{'from': 3, 'data': ('weight', '\x02'), 'to': 7}], 'notboldnot'),
-
- ([{'from': 3, 'data': ('underline', '\x1f'), 'to': 12}], 'notunderlinenot'),
-
- ([{'from': 0, 'data': ('weight', '\x02'), 'to': 2}, {'from': 0, 'data': ('underline', '\x1f'), 'to': 2}], 'Hi'),
-
- ([{'from': 3, 'data': ('foreground', '#FFFFFF'), 'to': 17}, {'from': 3, 'data': ('background', '#000000'), 'to': 17}, {'from': 17, 'data': ('foreground', '#FF0000'), 'to': 29}, {'from': 17, 'data': ('background', '#000000'), 'to': 29}], 'notwhite-on-blackred-on-blacknothing'),
-
- ([{'from': 0, 'data': ('foreground', '#0000CC'), 'to': 1}, {'from': 5, 'data': ('foreground', '#0000CC'), 'to': 6}], '<nick> text'),
-
- ([{'from': 0, 'data': ('foreground', '#770077'), 'to': 31}, {'from': 0, 'data': ('background', '#FFFFFF'), 'to': 31}, {'from': 31, 'data': ('foreground', '#000077'), 'to': 51}, {'from': 31, 'data': ('background', '#FFFFFF'), 'to': 51}], 'bersirc color with background! setting foreground! reset!'),
-
- ([], '7700,FFFFbersirc'),
-
- ([{'from': 0, 'data': ('foreground', '#0000FF'), 'to': 6}], '3Hello'),
-
- ([{'from': 0, 'data': ('foreground', '#0000FF'), 'to': 6}], ',Hello'),
-
- ([{'from': 0, 'data': ('foreground', '#FF0000'), 'to': 5}], 'Hello'),
-
- ([{'from': 2, 'data': ('weight', '\x02'), 'to': 4}], 'Bold'),
-
- ([{'from': 0, 'data': ('foreground', '#FF0000'), 'to': 5}, {'from': 0, 'data': ('background', '#7F0000'), 'to': 5}, {'from': 5, 'data': ('foreground', '#9C009C'), 'to': 12}, {'from': 5, 'data': ('background', '#7F0000'), 'to': 12}], 'HelloGoodbye'),
-
- ([{'from': 0, 'data': ('foreground', '#FF0000'), 'to': 5}, {'from': 0, 'data': ('background', '#00FF00'), 'to': 5}, {'from': 5, 'data': ('foreground', '#0000FF'), 'to': 12}, {'from': 5, 'data': ('background', '#00FF00'), 'to': 12}], 'HelloGoodbye'),
-
- ([{'from': 0, 'data': ('foreground', '#777777'), 'to': 1}, {'from': 1, 'data': ('foreground', '#00CCCC'), 'to': 6}, {'from': 6, 'data': ('foreground', '#777777'), 'to': 7}], '(stuff)'),
-
- ([{'from': 0, 'data': ('foreground', '#FF7F00'), 'to': 6}, {'from': 6, 'data': ('foreground', '#CCCCCC'), 'to': 10}, {'from': 10, 'data': ('foreground', '#FF7F00'), 'to': 16}], 'orangegreyorange'),
-
- ([{'from': 0, 'data': ('foreground', '#CCCCCC'), 'to': 3}, {'from': 0, 'data': ('background', '#444444'), 'to': 3}, {'from': 3, 'data': ('foreground', '#FF0000'), 'to': 6}, {'from': 3, 'data': ('background', '#444444'), 'to': 6}], 'sdfjkl'),
-
- ([{'from': 2, 'data': ('weight', '\x02'), 'to': 2}], '03,trixy'),
-
- ([{'from': 0, 'data': ('weight', '\x02'), 'to': 0}, {'from': 0, 'data': ('foreground', '#FFFFFF'), 'to': 24}], ',000000trixy for bersirc'),
- ]
-
- #"""
-
- #r = range(20000)
- #for i in r:
- # for test in tests:
- # parse_mirc(test)
-
- """
-
- lines = [eval(line.strip()) for line in file("parse_mirc_torture_test.txt")]
-
- for r in range(100):
- for line in lines:
- parse_mirc(line)
-
- #"""
-
- def setify_tags(tags):
- return set(frozenset(tag.iteritems()) for tag in tags if tag['from'] != tag['to'])
-
- def parsed_eq((tags1, text1), (tags2, text2)):
- return setify_tags(tags1) == setify_tags(tags2) and text1 == text2
-
- def parsed_to_unparsed((tags, text)):
- result = []
- for i, char in enumerate(text):
- result.append((
- dict(tag['data'] for tag in tags if tag['from'] <= i < tag['to']),
- char))
- return result
-
- for i, (test, result) in enumerate(zip(tests, results)):
- if not parsed_eq(parse_mirc(test), result):
- print "parse_mirc failed test %s:" % i
- print repr(test)
- print parse_mirc(test)
- print result
- print
-
- elif not parsed_eq(parse_mirc(unparse_mirc(parsed_to_unparsed(result))), result):
- print "unparse_mirc failed test %s:" % i
- print repr(test)
- print unparse_mirc(test)
- print
-
-#import dis
-#dis.dis(parse_mirc)
diff --git a/services/console/lib/purk/scripts/Makefile.am b/services/console/lib/purk/scripts/Makefile.am
deleted file mode 100644
index 00ffbf8..0000000
--- a/services/console/lib/purk/scripts/Makefile.am
+++ /dev/null
@@ -1,16 +0,0 @@
-sugardir = $(pkgdatadir)/services/console/lib/purk/scripts
-
-sugar_PYTHON = \
- alias.py \
- chaninfo.py \
- clicks.py \
- completion.py \
- console.py \
- history.py \
- ignore.py \
- irc_script.py \
- keys.py \
- theme.py \
- timeout.py \
- ui_script.py
-
diff --git a/services/console/lib/purk/scripts/alias.py b/services/console/lib/purk/scripts/alias.py
deleted file mode 100755
index ffd213d..0000000
--- a/services/console/lib/purk/scripts/alias.py
+++ /dev/null
@@ -1,60 +0,0 @@
-import sys
-import os
-
-from conf import conf
-
-aliases = conf.get("aliases",{
- 'op':'"mode "+window.id+" +"+"o"*len(args)+" "+" ".join(args)',
- 'deop':'"mode "+window.id+" -"+"o"*len(args)+" "+" ".join(args)',
- 'voice':'"mode "+window.id+" +"+"v"*len(args)+" "+" ".join(args)',
- 'devoice':'"mode "+window.id+" -"+"v"*len(args)+" "+" ".join(args)',
- 'umode':'"mode "+network.me+" "+" ".join(args)',
- 'clear':'window.output.clear()',
- })
-
-class CommandHandler:
- __slots__ = ["command"]
- def __init__(self, command):
- self.command = command
- def __call__(self, e):
- loc = sys.modules.copy()
- loc.update(e.__dict__)
- result = eval(self.command,loc)
- if isinstance(result,basestring):
- core.events.run(result,e.window,e.network)
-
-for name in aliases:
- globals()['onCommand'+name.capitalize()] = CommandHandler(aliases[name])
-
-def onCommandAlias(e):
- if e.args and 'r' in e.switches:
- name = e.args[0].lower()
- command = aliases[name]
- del aliases[name]
- conf['aliases'] = aliases
- e.window.write("* Deleted alias %s%s (was %s)" % (conf.get('command-prefix','/'),name,command))
- core.events.load(__name__,reloading=True)
- elif 'l' in e.switches:
- e.window.write("* Current aliases:")
- for i in aliases:
- e.window.write("* %s%s: %s" % (conf.get('command-prefix','/'),i,aliases[i]))
- elif len(e.args) >= 2:
- name = e.args[0].lower()
- command = ' '.join(e.args[1:])
- aliases[name] = command
- conf['aliases'] = aliases
- e.window.write("* Created an alias %s%s to %s" % (conf.get('command-prefix','/'),name,command))
- core.events.reload(__name__)
- elif len(e.args) == 1:
- name = e.args[0].lower()
- if name in aliases:
- e.window.write("* %s%s is an alias to %s" % (conf.get('command-prefix','/'),name,aliases[name]))
- else:
- e.window.write("* There is no alias %s%s" % (conf.get('command-prefix','/'),name))
- else:
- e.window.write(
-"""Usage:
- /alias \x02name\x02 \x02expression\x02 to create or replace an alias
- /alias \x02name\x02 to look at an alias
- /alias -r \x02name\x02 to remove an alias
- /alias -l to see a list of aliases""")
diff --git a/services/console/lib/purk/scripts/chaninfo.py b/services/console/lib/purk/scripts/chaninfo.py
deleted file mode 100644
index e6ff3a0..0000000
--- a/services/console/lib/purk/scripts/chaninfo.py
+++ /dev/null
@@ -1,320 +0,0 @@
-import windows
-
-def _justprefix(network, channel, nick):
- fr, to = network.isupport["PREFIX"][1:].split(")")
-
- for mode, prefix in zip(fr, to):
- if mode in channel.nicks.get(nick, ''):
- return prefix
-
- return ''
-
-def prefix(network, channelname, nick):
- channel = getchan(network, channelname)
-
- if channel:
- nick = '%s%s' % (_justprefix(network, channel, nick), nick)
-
- return nick
-
-def escape(string):
- for escapes in (('&','&amp;'), ('<','&lt;'), ('>','&gt;')):
- string = string.replace(*escapes)
- return string
-
-def sortkey(network, channelname, nick):
- chanmodes, dummy = network.isupport["PREFIX"][1:].split(")")
- nickmodes = mode(network, channelname, nick)
-
- return '%s%s' % (''.join(str(int(mode not in nickmodes)) for mode in chanmodes), network.norm_case(nick))
-
-def nicklist_add(network, channel, nick):
- window = windows.get(windows.ChannelWindow, network, channel.name, core)
- #window = core.window
- if window:
- window.nicklist.append(nick, escape(prefix(network, channel.name, nick)), sortkey(network, channel.name, nick))
-
-def nicklist_del(network, channel, nick):
- window = windows.get(windows.ChannelWindow, network, channel.name, core)
- #window = core.window
- if window:
- try:
- window.nicklist.remove(nick)
- except ValueError:
- pass
-
-def setupListRightClick(e):
- if isinstance(e.window, windows.ChannelWindow):
- #if isinstance(core.window, windows.ChannelWindow):
- #if e.data[0] in e.window.network.isupport["PREFIX"].split(")")[1]:
- if e.data[0] in core.window.network.isupport["PREFIX"].split(")")[1]:
- e.nick = e.data[1:]
- else:
- e.nick = e.data
-
-def setupSocketConnect(e):
- e.network.channels = {}
-
-def setdownDisconnect(e):
- e.network.channels = {}
-
-class Channel(object):
- def __init__(self, name):
- self.name = name
- self.nicks = {}
- self.normal_nicks = {} # mapping of normal nicks to actual nicks
- self.getting_names = False #are we between lines in a /names reply?
- self.mode = ''
- self.special_mode = {} #for limits, keys, and anything similar
- self.topic = ''
- self.got_mode = False #did we get at least one mode reply?
- self.got_names = False #did we get at least one names reply?
-
-def getchan(network, channel):
- return hasattr(network, 'channels') and network.channels.get(network.norm_case(channel))
-
-#return a list of channels you're on on the given network
-def channels(network):
- if not hasattr(network, 'channels'):
- network.channels = {}
-
- return list(network.channels)
-
-#return True if you're on the channel
-def ischan(network, channel):
- return bool(getchan(network, channel))
-
-#return True if the nick is on the channel
-def ison(network, channel, nickname):
- channel = getchan(network, channel)
- return channel and network.norm_case(nickname) in channel.normal_nicks
-
-#return a list of nicks on the given channel
-def nicks(network, channel):
- channel = getchan(network, channel)
-
- if channel:
- return channel.nicks
- else:
- return {}
-
-#return the mode on the given channel
-def mode(network, channel, nickname=''):
- channel = getchan(network, channel)
-
- if channel:
- if nickname:
- realnick = channel.normal_nicks.get(network.norm_case(nickname))
- if realnick:
- return channel.nicks[realnick]
-
- else:
- result = channel.mode
- for m in channel.mode:
- if m in channel.special_mode:
- result += ' '+channel.special_mode[m]
- return result
-
- return ''
-
-#return the topic on the given channel
-def topic(network, channel):
- channel = getchan(network, channel)
-
- if channel:
- return channel.topic
- else:
- return ''
-
-def setupJoin(e):
- print e
- if e.source == e.network.me:
- e.network.channels[e.network.norm_case(e.target)] = Channel(e.target)
- e.network.raw('MODE '+e.target)
-
- #if we wanted to be paranoid, we'd account for not being on the channel
- channel = getchan(e.network,e.target)
- channel.nicks[e.source] = ''
- channel.normal_nicks[e.network.norm_case(e.source)] = e.source
-
- if e.source == e.network.me:
- #If the channel window already existed, and we're joining, then we
- #didn't clear out the nicklist when we left. That means we have to clear
- #it out now.
- window = windows.get(windows.ChannelWindow, e.network, e.target, core)
- #window = core.window
- #print core
- if window:
- window.nicklist.clear()
-
- nicklist_add(e.network, channel, e.source)
-
-def setdownPart(e):
- if e.source == e.network.me:
- del e.network.channels[e.network.norm_case(e.target)]
- else:
- channel = getchan(e.network,e.target)
- nicklist_del(e.network, channel, e.source)
- del channel.nicks[e.source]
- del channel.normal_nicks[e.network.norm_case(e.source)]
-
-def setdownKick(e):
- if e.target == e.network.me:
- del e.network.channels[e.network.norm_case(e.channel)]
- else:
- channel = getchan(e.network,e.channel)
- nicklist_del(e.network, channel, e.target)
- del channel.nicks[e.target]
- del channel.normal_nicks[e.network.norm_case(e.target)]
-
-def setdownQuit(e):
- #if paranoid: check if e.source is me
- for channame in channels(e.network):
- channel = getchan(e.network,channame)
- if e.source in channel.nicks:
- nicklist_del(e.network, channel, e.source)
- del channel.nicks[e.source]
- del channel.normal_nicks[e.network.norm_case(e.source)]
-
-def setupMode(e):
- channel = getchan(e.network,e.channel)
- if channel:
- user_modes = e.network.isupport['PREFIX'].split(')')[0][1:]
-
- (list_modes,
- always_parm_modes,
- set_parm_modes,
- normal_modes) = e.network.isupport['CHANMODES'].split(',')
-
- list_modes += user_modes
-
- mode_on = True #are we reading a + section or a - section?
- params = e.text.split(' ')
-
- for char in params.pop(0):
- if char == '+':
- mode_on = True
-
- elif char == '-':
- mode_on = False
-
- else:
- if char in user_modes:
- #these are modes like op and voice
- nickname = params.pop(0)
- nicklist_del(e.network, channel, nickname)
- if mode_on:
- channel.nicks[nickname] += char
- else:
- channel.nicks[nickname] = channel.nicks[nickname].replace(char, '')
- nicklist_add(e.network, channel, nickname)
-
- elif char in list_modes:
- #things like ban/unban
- #FIXME: We don't keep track of those lists here, but we know
- # when they're changed and how. Scriptors should be able to
- # take advantage of this
- params.pop(0)
-
- elif char in always_parm_modes:
- #these always have a parameter
- param = params.pop(0)
-
- if mode_on:
- channel.special_mode[char] = param
- else:
- #account for unsetting modes that aren't set
- channel.special_mode.pop(char, None)
-
- elif char in set_parm_modes:
- #these have a parameter only if they're being set
- if mode_on:
- channel.special_mode[char] = params.pop(0)
- else:
- #account for unsetting modes that aren't set
- channel.special_mode.pop(char, None)
-
- if char not in list_modes:
- if mode_on:
- channel.mode = channel.mode.replace(char, '')+char
- else:
- channel.mode = channel.mode.replace(char, '')
-
-def setdownNick(e):
- for channame in channels(e.network):
- channel = getchan(e.network,channame)
- if e.source in channel.nicks:
- nicklist_del(e.network, channel, e.source)
- del channel.normal_nicks[e.network.norm_case(e.source)]
- channel.nicks[e.target] = channel.nicks[e.source]
- del channel.nicks[e.source]
- channel.normal_nicks[e.network.norm_case(e.target)] = e.target
- nicklist_add(e.network, channel, e.target)
-
-def setupTopic(e):
- channel = getchan(e.network, e.target)
- if channel:
- channel.topic = e.text
-
-def setupRaw(e):
- if e.msg[1] == '353': #names reply
- channel = getchan(e.network,e.msg[4])
- if channel:
- if not channel.getting_names:
- channel.nicks.clear()
- channel.normal_nicks.clear()
- channel.getting_names = True
- if not channel.got_names:
- e.quiet = True
- for nickname in e.msg[5].split(' '):
- if nickname:
- if not nickname[0].isalpha() and nickname[0] in e.network.prefixes:
- n = nickname[1:]
- channel.nicks[n] = e.network.prefixes[nickname[0]]
- channel.normal_nicks[e.network.norm_case(n)] = n
- else:
- channel.nicks[nickname] = ''
- channel.normal_nicks[e.network.norm_case(nickname)] = nickname
-
- elif e.msg[1] == '366': #end of names reply
- channel = getchan(e.network,e.msg[3])
- if channel:
- if not channel.got_names:
- e.quiet = True
- channel.got_names = True
- channel.getting_names = False
-
- window = windows.get(windows.ChannelWindow, e.network, e.msg[3], core)
- if window:
- window.nicklist.replace(
- (nick, escape(prefix(e.network, channel.name, nick)), sortkey(e.network, channel.name, nick)) for nick in channel.nicks
- )
-
- elif e.msg[1] == '324': #channel mode is
- channel = getchan(e.network,e.msg[3])
- if channel:
- if not channel.got_mode:
- e.quiet = True
- channel.got_mode = True
- mode = e.msg[4]
- params = e.msg[:4:-1]
- list_modes, always_parm_modes, set_parm_modes, normal_modes = \
- e.network.isupport['CHANMODES'].split(',')
- parm_modes = always_parm_modes + set_parm_modes
- channel.mode = e.msg[4]
- channel.special_mode.clear()
- for char in channel.mode:
- if char in parm_modes:
- channel.special_mode[char] = params.pop()
-
- elif e.msg[1] == '331': #no topic
- channel = getchan(e.network,e.msg[3])
- if channel:
- channel.topic = ''
-
- elif e.msg[1] == '332': #channel topic is
- channel = getchan(e.network,e.msg[3])
- if channel:
- channel.topic = e.text
-
-#core.events.load(__name__)
diff --git a/services/console/lib/purk/scripts/clicks.py b/services/console/lib/purk/scripts/clicks.py
deleted file mode 100644
index b2f3f82..0000000
--- a/services/console/lib/purk/scripts/clicks.py
+++ /dev/null
@@ -1,146 +0,0 @@
-import ui
-import windows
-import chaninfo
-from conf import conf
-
-def set_target(e):
- target_l = e.target.lstrip('@+%.(<')
- e._target_fr = e.target_fr + len(e.target) - len(target_l)
-
- target_r = e.target.rstrip('>:,')
- e._target_to = e.target_to - len(e.target) + len(target_r)
-
- if target_r.endswith(')'):
- e._target = e.text[e._target_fr:e._target_to]
- open_parens = e._target.count('(') - e._target.count(')')
- while open_parens < 0 and e.text[e._target_to-1] == ')':
- e._target_to -= 1
- open_parens += 1
-
- e._target = e.text[e._target_fr:e._target_to]
-
-def is_nick(e):
- return isinstance(e.window, windows.ChannelWindow) and \
- chaninfo.ison(e.window.network, e.window.id, e._target)
-
-def is_url(e):
- def starts(prefix, mindots=1):
- def prefix_url(target):
- return target.startswith(prefix) and target.count('.') >= mindots
-
- return prefix_url
-
- to_check = [starts(*x) for x in [
- ('http://', 1),
- ('https://', 1),
- ('ftp://', 1),
- ('www', 2),
- ]]
-
- for check_url in to_check:
- if check_url(e._target):
- return True
-
- return False
-
-def is_chan(e):
- # click on a #channel
- return e.window.network and e._target and \
- e._target[0] in e.window.network.isupport.get('CHANTYPES', '&#$+')
-
-def get_autojoin_list(network):
- perform = conf.get('networks',{}).get(network.name,{}).get('perform',())
- channels = set()
- for line in perform:
- if line.startswith('join ') and ' ' not in line[5:]:
- channels.update(line[5:].split(','))
- return channels
-
-def add_autojoin(network, channel):
- if 'networks' not in conf:
- conf['networks'] = {}
- if network.name not in conf['networks']:
- conf['networks'][network.name] = {'server': network.server}
- conf['start_networks'] = conf.get('start_networks',[]) + [network.name]
- if 'perform' in conf['networks'][network.name]:
- perform = conf['networks'][network.name]['perform']
- else:
- perform = conf['networks'][network.name]['perform'] = []
-
- for n, line in enumerate(perform):
- if line.startswith('join ') and ' ' not in line[5:]:
- perform[n] = "%s,%s" % (line, channel)
- break
- else:
- perform.append('join %s' % channel)
-
-def make_nick_menu(e, target):
- def query():
- core.events.run('query %s' % target, e.window, e.window.network)
-
- def whois():
- core.events.run('whois %s' % target, e.window, e.window.network)
-
- e.menu += [
- ('Query', query),
- ('Whois', whois),
- (),
- ]
-
-def onHover(e):
- set_target(e)
-
- for is_check in (is_nick, is_url, is_chan):
- if is_check(e):
- e.tolink.add((e._target_fr, e._target_to))
- break
-
-def onClick(e):
- set_target(e)
-
- if is_nick(e):
- core.events.run('query %s' % e._target, e.window, e.window.network)
-
- # url of the form http://xxx.xxx or www.xxx.xxx
- elif is_url(e):
- if e._target.startswith('www'):
- e._target = 'http://%s' % e._target
- ui.open_file(e._target)
-
- # click on a #channel
- elif is_chan(e):
- if not chaninfo.ischan(e.window.network, e._target):
- e.window.network.join(e._target)
- window = windows.get(windows.ChannelWindow, e.window.network, e._target)
- if window:
- window.activate()
-
-def onRightClick(e):
- set_target(e)
-
- # nick on this channel
- if is_nick(e):
- make_nick_menu(e, e._target)
-
- elif is_url(e):
- if e._target.startswith('www'):
- e._target = 'http://%s' % e._target
-
- def copy_to():
- # copy to clipboard
- ui.set_clipboard(e._target)
-
- e.menu += [('Copy', copy_to)]
-
- elif is_chan(e):
- e.channel = e._target
- e.network = e.window.network
- core.events.trigger('ChannelMenu', e)
-
-def onListRightClick(e):
- if isinstance(e.window, windows.ChannelWindow):
- make_nick_menu(e, e.nick)
-
-def onListDoubleClick(e):
- if isinstance(e.window, windows.ChannelWindow):
- core.events.run("query %s" % e.target, e.window, e.window.network)
diff --git a/services/console/lib/purk/scripts/completion.py b/services/console/lib/purk/scripts/completion.py
deleted file mode 100644
index 1719702..0000000
--- a/services/console/lib/purk/scripts/completion.py
+++ /dev/null
@@ -1,135 +0,0 @@
-import windows
-import chaninfo
-from conf import conf
-
-def channel_completer(window, left, right, text):
- if isinstance(window, windows.ChannelWindow):
- yield window.id
-
- for w in windows.get_with(wclass=windows.ChannelWindow, network=window.network):
- if w is not window:
- yield w.id
-
- for w in windows.get_with(wclass=windows.ChannelWindow):
- if w.network is not window.network:
- yield w.id
-
-# normal server commands
-srv_commands = ('ping', 'join', 'part', 'mode', 'server', 'kick',
- 'quit', 'nick', 'privmsg', 'notice', 'topic')
-
-def command_completer(window, left, right, text):
- for c in srv_commands:
- yield '/%s' % c
-
- if 'CMDS' in window.network.isupport:
- for c in window.network.isupport['CMDS'].split(','):
- yield '/%s' % c.lower()
-
- for c in core.events.all_events:
- if c.startswith('Command') and c != 'Command':
- yield '/%s' % c[7:].lower()
-
-def nick_completer(window, left, right, text):
- if type(window) == windows.QueryWindow:
- yield window.id
-
- recent_speakers = getattr(window, 'recent_speakers', ())
-
- for nick in recent_speakers:
- if chaninfo.ison(window.network, window.id, nick):
- yield nick
-
- for nick in chaninfo.nicks(window.network, window.id):
- if nick not in recent_speakers:
- yield nick
-
-def script_completer(window, left, right, text):
- return core.events.loaded.iterkeys()
-
-def network_completer(window, left, right, text):
- return conf.get('networks', {}).iterkeys()
-
-def get_completer_for(window):
- input = window.input
-
- left, right = input.text[:input.cursor], input.text[input.cursor:]
-
- text = left.split(' ')[-1]
-
- while True:
- suffix = ''
- if text and text[0] in window.network.isupport.get('CHANTYPES', '#&+'):
- candidates = channel_completer(window, left, right, text)
-
- elif input.text.startswith('/reload '):
- candidates = script_completer(window, left, right, text)
-
- elif input.text.startswith('/edit '):
- candidates = script_completer(window, left, right, text)
-
- elif input.text.startswith('/server '):
- candidates = network_completer(window, left, right, text)
-
- elif text.startswith('/'):
- candidates = command_completer(window, left, right, text)
- suffix = ' '
-
- else:
- candidates = nick_completer(window, left, right, text)
-
- if left == text:
- suffix = ': '
- else:
- suffix = ' '
-
- if text:
- before = left[:-len(text)]
- else:
- before = left
-
- insert_text = '%s%s%s%s' % (before, '%s', suffix, right)
- cursor_pos = len(before + suffix)
-
- original = window.input.text, window.input.cursor
-
- for cand in candidates:
- if cand.lower().startswith(text.lower()):
- window.input.text, window.input.cursor = insert_text % cand, cursor_pos + len(cand)
- yield None
-
- window.input.text, window.input.cursor = original
- yield None
-
-# generator--use recent_completer.next() to continue cycling through whatever
-recent_completer = None
-
-def onKeyPress(e):
- global recent_completer
-
- if e.key == 'Tab':
- if not recent_completer:
- recent_completer = get_completer_for(e.window)
-
- recent_completer.next()
-
- else:
- recent_completer = None
-
-def onActive(e):
- global recent_completer
-
- recent_completer = None
-
-def onText(e):
- if chaninfo.ischan(e.network, e.target):
- if not hasattr(e.window, 'recent_speakers'):
- e.window.recent_speakers = []
-
- for nick in e.window.recent_speakers:
- if nick == e.source or not chaninfo.ison(e.network, e.target, nick):
- e.window.recent_speakers.remove(nick)
-
- e.window.recent_speakers.insert(0, e.source)
-
-onAction = onText
diff --git a/services/console/lib/purk/scripts/console.py b/services/console/lib/purk/scripts/console.py
deleted file mode 100755
index bef8e0e..0000000
--- a/services/console/lib/purk/scripts/console.py
+++ /dev/null
@@ -1,68 +0,0 @@
-import sys
-import traceback
-import windows
-from conf import conf
-
-class ConsoleWriter:
- __slots__ = ['window']
- def __init__(self, window):
- self.window = window
- def write(self, text):
- try:
- self.window.write(text, line_ending='')
- except:
- self.window.write(traceback.format_exc())
-
-class ConsoleWindow(windows.SimpleWindow):
- def __init__(self, network, id):
- windows.SimpleWindow.__init__(self, network, id)
-
- writer = ConsoleWriter(self)
-
- sys.stdout = writer
- sys.stderr = writer
-
- self.globals = {'window': self}
- self.locals = {}
-
-#this prevents problems (and updates an open console window) on reload
-#window = None
-#for window in manager:
-# if type(window).__name__ == "ConsoleWindow":
-# window.mutate(ConsoleWindow, window.network, window.id)
-#del window
-
-def onClose(e):
- if isinstance(e.window, ConsoleWindow):
- sys.stdout = sys.__stdout__
- sys.stderr = sys.__stderr__
-
-def onCommandConsole(e):
- windows.new(ConsoleWindow, None, "console").activate()
-
-def onCommandSay(e):
- if isinstance(e.window, ConsoleWindow):
- import pydoc #fix nonresponsive help() command
- old_pager, pydoc.pager = pydoc.pager, pydoc.plainpager
- e.window.globals.update(sys.modules)
- text = ' '.join(e.args)
- try:
- e.window.write(">>> %s" % text)
- result = eval(text, e.window.globals, e.window.locals)
- if result is not None:
- e.window.write(repr(result))
- e.window.globals['_'] = result
- except SyntaxError:
- try:
- exec text in e.window.globals, e.window.locals
- except:
- traceback.print_exc()
- except:
- traceback.print_exc()
- pydoc.pager = old_pager
- else:
- raise core.events.CommandError("There's no one here to speak to.")
-
-def onStart(e):
- if conf.get('start-console'):
- windows.new(ConsoleWindow, None, "console")
diff --git a/services/console/lib/purk/scripts/history.py b/services/console/lib/purk/scripts/history.py
deleted file mode 100644
index 379ad5e..0000000
--- a/services/console/lib/purk/scripts/history.py
+++ /dev/null
@@ -1,45 +0,0 @@
-def onKeyPress(e):
- if not hasattr(e.window, 'history'):
- e.window.history = [], -1
-
- if e.key in ('Up', 'Down'):
- h, i = e.window.history
-
- if i == -1 and e.window.input.text:
- h.insert(0, e.window.input.text)
- i = 0
-
- if e.key == 'Up':
- i += 1
-
- if i < len(h):
- e.window.history = h, i
-
- e.window.input.text = h[i]
- e.window.input.cursor = -1
-
- else: # e.key == 'Up'
- i -= 1
-
- if i > -1:
- e.window.history = h, i
-
- e.window.input.text = h[i]
- e.window.input.cursor = -1
-
- elif i == -1:
- e.window.history = h, i
-
- e.window.input.text = ''
- e.window.input.cursor = -1
-
-def onInput(e):
- if not hasattr(e.window, 'history'):
- e.window.history = [], -1
-
- if e.text:
- h, i = e.window.history
-
- h.insert(0, e.text)
-
- e.window.history = h, -1
diff --git a/services/console/lib/purk/scripts/ignore.py b/services/console/lib/purk/scripts/ignore.py
deleted file mode 100755
index 98b4eed..0000000
--- a/services/console/lib/purk/scripts/ignore.py
+++ /dev/null
@@ -1,43 +0,0 @@
-from conf import conf
-import irc
-
-def preRaw(e):
- if e.msg[1] in ('PRIVMSG','NOTICE'):
- address = e.network.norm_case('%s!%s' % (e.source, e.address))
- for mask in conf.get('ignore_masks',()):
- if irc.match_glob(address, e.network.norm_case(mask)):
- core.events.halt()
-
-def onCommandIgnore(e):
- if 'ignore_masks' not in conf:
- conf['ignore_masks'] = []
- if 'l' in e.switches:
- for i in conf['ignore_masks']:
- e.window.write('* %s' % i)
- elif 'c' in e.switches:
- del conf['ignore_masks']
- e.window.write('* Cleared the ignore list.')
- elif e.args:
- if '!' in e.args[0] or '*' in e.args[0] or '?' in e.args[0]:
- mask = e.args[0]
- else:
- mask = '%s!*' % e.args[0]
- if 'r' in e.switches:
- if mask in conf['ignore_masks']:
- conf['ignore_masks'].remove(mask)
- e.window.write('* Removed %s from the ignore list' % e.args[0])
- else:
- raise core.events.CommandError("Couldn't find %s in the ignore list" % e.args[0])
- else:
- if mask in conf['ignore_masks']:
- e.window.write('* %s is already ignored' % e.args[0])
- else:
- conf['ignore_masks'].append(mask)
- e.window.write('* Ignoring messages from %s' % e.args[0])
- else:
- e.window.write(
-"""Usage:
- /ignore \x02nick/mask\x02 to ignore a nickname or mask
- /ignore -r \x02nick/mask\x02 to stop ignoring a nickname or mask
- /ignore -l to view the ignore list
- /ignore -c to clear the ignore list""")
diff --git a/services/console/lib/purk/scripts/irc_script.py b/services/console/lib/purk/scripts/irc_script.py
deleted file mode 100644
index 4582d72..0000000
--- a/services/console/lib/purk/scripts/irc_script.py
+++ /dev/null
@@ -1,588 +0,0 @@
-import time
-
-from conf import conf
-import ui
-import windows
-import irc
-
-COMMAND_PREFIX = conf.get('command_prefix', '/')
-
-NICK_SUFFIX = r"`_-\|0123456789"
-
-_hextochr = dict(('%02x' % i, chr(i)) for i in range(256))
-def unquote(url, rurl=""):
-
- while '%' in url:
- url, char = url.rsplit('%', 1)
-
- chars = char[:2].lower()
-
- if chars in _hextochr:
- rurl = '%s%s%s' % (_hextochr[chars], char[2:], rurl)
- else:
- rurl = "%s%s%s" % ('%', char, rurl)
-
- return url + rurl
-
-#for getting a list of alternative nicks to try on a network
-def _nick_generator(network):
- for nick in network.nicks[1:]:
- yield nick
- if network._nick_error:
- nick = 'ircperson'
- else:
- nick = network.nicks[0]
- import itertools
- for i in itertools.count(1):
- for j in xrange(len(NICK_SUFFIX)**i):
- suffix = ''.join(NICK_SUFFIX[(j/(len(NICK_SUFFIX)**x))%len(NICK_SUFFIX)] for x in xrange(i))
- if network._nick_max_length:
- yield nick[0:network._nick_max_length-i]+suffix
- else:
- yield nick+suffix
-
-def setdownRaw(e):
- if not e.done:
- if not e.network.got_nick:
- if e.msg[1] in ('432','433','436','437'): #nickname unavailable
- failednick = e.msg[3]
- nicks = list(e.network.nicks)
-
- if hasattr(e.network,'_nick_generator'):
- if len(failednick) < len(e.network._next_nick):
- e.network._nick_max_length = len(failednick)
- e.network._next_nick = e.network._nick_generator.next()
- e.network.raw('NICK %s' % e.network._next_nick)
- e.network._nick_error |= (e.msg[1] == '432')
- else:
- e.network._nick_error = (e.msg[1] == '432')
- if len(failednick) < len(e.network.nicks[0]):
- e.network._nick_max_length = len(failednick)
- else:
- e.network._nick_max_length = 0
- e.network._nick_generator = _nick_generator(e.network)
- e.network._next_nick = e.network._nick_generator.next()
- e.network.raw('NICK %s' % e.network._next_nick)
-
- elif e.msg[1] == '431': #no nickname given--this shouldn't happen
- pass
-
- elif e.msg[1] == '001':
- e.network.got_nick = True
- if e.network.me != e.msg[2]:
- core.events.trigger(
- 'Nick', network=e.network, window=e.window,
- source=e.network.me, target=e.msg[2], address='',
- text=e.msg[2]
- )
- e.network.me = e.msg[2]
- if hasattr(e.network,'_nick_generator'):
- del e.network._nick_generator, e.network._nick_max_length, e.network._next_nick
-
- if e.msg[1] == "PING":
- e.network.raw("PONG :%s" % e.msg[-1])
- e.done = True
-
- elif e.msg[1] == "JOIN":
- e.channel = e.target
- e.requested = e.network.norm_case(e.channel) in e.network.requested_joins
- core.events.trigger("Join", e)
- e.done = True
-
- elif e.msg[1] == "PART":
- e.channel = e.target
- e.requested = e.network.norm_case(e.channel) in e.network.requested_parts
- e.text = ' '.join(e.msg[3:])
- core.events.trigger("Part", e)
- e.done = True
-
- elif e.msg[1] in "MODE":
- e.channel = e.target
- e.text = ' '.join(e.msg[3:])
- core.events.trigger("Mode", e)
- e.done = True
-
- elif e.msg[1] == "QUIT":
- core.events.trigger('Quit', e)
- e.done = True
-
- elif e.msg[1] == "KICK":
- e.channel = e.msg[2]
- e.target = e.msg[3]
- core.events.trigger('Kick', e)
- e.done = True
-
- elif e.msg[1] == "NICK":
- core.events.trigger('Nick', e)
- if e.network.me == e.source:
- e.network.me = e.target
-
- e.done = True
-
- elif e.msg[1] == "PRIVMSG":
- core.events.trigger('Text', e)
- e.done = True
-
- elif e.msg[1] == "NOTICE":
- core.events.trigger('Notice', e)
- e.done = True
-
- elif e.msg[1] == "TOPIC":
- core.events.trigger('Topic', e)
- e.done = True
-
- elif e.msg[1] in ("376", "422"): #RPL_ENDOFMOTD
- if e.network.status == irc.INITIALIZING:
- e.network.status = irc.CONNECTED
- core.events.trigger('Connect', e)
- e.done = True
-
- elif e.msg[1] == "470": #forwarded from channel X to channel Y
- if e.network.norm_case(e.msg[3]) in e.network.requested_joins:
- e.network.requested_joins.discard(e.network.norm_case(e.msg[3]))
- e.network.requested_joins.add(e.network.norm_case(e.msg[4]))
-
- elif e.msg[1] == "005": #RPL_ISUPPORT
- for arg in e.msg[3:]:
- if ' ' not in arg: #ignore "are supported by this server"
- if '=' in arg:
- name, value = arg.split('=', 1)
- if value.isdigit():
- value = int(value)
- else:
- name, value = arg, ''
-
- #Workaround for broken servers (bahamut on EnterTheGame)
- if name == 'PREFIX' and value[0] != '(':
- continue
-
- #in theory, we're supposed to replace \xHH with the
- # corresponding ascii character, but I don't think anyone
- # really does this
- e.network.isupport[name] = value
-
- if name == 'PREFIX':
- new_prefixes = {}
- modes, prefixes = value[1:].split(')')
- for mode, prefix in zip(modes, prefixes):
- new_prefixes[mode] = prefix
- new_prefixes[prefix] = mode
- e.network.prefixes = new_prefixes
-
-def setupSocketConnect(e):
- e.network.got_nick = False
- e.network.isupport = {
- 'NETWORK': e.network.server,
- 'PREFIX': '(ohv)@%+',
- 'CHANMODES': 'b,k,l,imnpstr',
- }
- e.network.prefixes = {'o':'@', 'h':'%', 'v':'+', '@':'o', '%':'h', '+':'v'}
- e.network.connect_timestamp = time.time()
- e.network.requested_joins.clear()
- e.network.requested_parts.clear()
- e.network.on_channels.clear()
- if hasattr(e.network,'_nick_generator'):
- del e.network._nick_generator, e.network._nick_max_length, e.network._next_nick
- if not e.done:
- #this needs to be tested--anyone have a server that uses PASS?
- if e.network.password:
- e.network.raw("PASS :%s" % e.network.password)
- e.network.raw("NICK %s" % e.network.nicks[0])
- e.network.raw("USER %s %s %s :%s" %
- (e.network.username, "8", "*", e.network.fullname))
- #per rfc2812 these are username, user mode flags, unused, realname
-
- #e.network.me = None
- e.done = True
-
-def onDisconnect(e):
- if hasattr(e.network,'_reconnect_source'):
- e.network._reconnect_source.unregister()
- del e.network._reconnect_source
- if hasattr(e.network,'connect_timestamp'):
- if e.error and conf.get('autoreconnect',True):
- delay = time.time() - e.network.connect_timestamp > 30 and 30 or 120
- def do_reconnect():
- if not e.network.status:
- server(network=e.network)
- def do_announce_reconnect():
- if not e.network.status:
- windows.get_default(e.network).write("* Will reconnect in %s seconds.." % delay)
- e.network._reconnect_source = ui.register_timer(delay*1000,do_reconnect)
- e.network._reconnect_source = ui.register_idle(do_announce_reconnect)
-
-def onCloseNetwork(e):
- e.network.quit()
- if hasattr(e.network,'_reconnect_source'):
- e.network._reconnect_source.unregister()
- del e.network._reconnect_source
-
-def setdownDisconnect(e):
- if hasattr(e.network,'connect_timestamp'):
- del e.network.connect_timestamp
-
-def setupInput(e):
- if not e.done:
- if e.text.startswith(COMMAND_PREFIX) and not e.ctrl:
- command = e.text[len(COMMAND_PREFIX):]
- else:
- command = 'say - %s' % e.text
-
- core.events.run(command, e.window, e.network)
-
- e.done = True
-
-def onCommandSay(e):
- if isinstance(e.window, windows.ChannelWindow) or isinstance(e.window, windows.QueryWindow):
- e.network.msg(e.window.id, ' '.join(e.args))
- else:
- raise core.events.CommandError("There's no one here to speak to.")
-
-def onCommandMsg(e):
- e.network.msg(e.args[0], ' '.join(e.args[1:]))
-
-def onCommandNotice(e):
- e.network.notice(e.args[0], ' '.join(e.args[1:]))
-
-def onCommandQuery(e):
- windows.new(windows.QueryWindow, e.network, e.args[0], core).activate()
- if len(e.args) > 1:
- message = ' '.join(e.args[1:])
- if message: #this is false if you do "/query nickname "
- e.network.msg(e.args[0], ' '.join(e.args[1:]))
-
-def setupJoin(e):
- if e.source == e.network.me:
- chan = e.network.norm_case(e.channel)
- e.network.on_channels.add(chan)
- e.network.requested_joins.discard(chan)
-
-def setdownPart(e):
- if e.source == e.network.me:
- chan = e.network.norm_case(e.channel)
- e.network.on_channels.discard(chan)
- e.network.requested_parts.discard(chan)
-
-def setdownKick(e):
- if e.target == e.network.me:
- chan = e.network.norm_case(e.channel)
- e.network.on_channels.discard(chan)
-
-def ischan(network, channel):
- return network.norm_case(channel) in network.on_channels
-
-# make /nick work offline
-def change_nick(network, nick):
- if not network.status:
- core.events.trigger(
- 'Nick',
- network=network, window=windows.get_default(network),
- source=network.me, target=nick, address='', text=nick
- )
- network.nicks[0] = nick
- network.me = nick
- else:
- network.raw('NICK :%s' % nick)
-
-def onCommandNick(e):
- default_nick = irc.default_nicks()[0]
- if 't' not in e.switches and e.network.me == default_nick:
- conf['nick'] = e.args[0]
- import conf as _conf
- _conf.save()
- for network in set(w.network for w in core.manager):
- if network.me == default_nick:
- change_nick(network, e.args[0])
- else:
- change_nick(e.network, e.args[0])
-
-def setdownNick(e):
- if e.source != e.network.me:
- window = windows.get(windows.QueryWindow, e.network, e.source)
- if window:
- window.id = e.target
-
-# make /quit always disconnect us
-def onCommandQuit(e):
- if e.network.status:
- e.network.quit(' '.join(e.args))
- else:
- raise core.events.CommandError("We're not connected to a network.")
-
-def onCommandRaw(e):
- if e.network.status >= irc.INITIALIZING:
- e.network.raw(' '.join(e.args))
- else:
- raise core.events.CommandError("We're not connected to a network.")
-
-onCommandQuote = onCommandRaw
-
-def onCommandJoin(e):
- if e.args:
- if e.network.status >= irc.INITIALIZING:
- e.network.join(' '.join(e.args), requested = 'n' not in e.switches)
- else:
- raise core.events.CommandError("We're not connected.")
- elif isinstance(e.window, windows.ChannelWindow):
- e.window.network.join(e.window.id, requested = 'n' not in e.switches)
- else:
- raise core.events.CommandError("You must supply a channel.")
-
-def onCommandPart(e):
- if e.args:
- if e.network.status >= irc.INITIALIZING:
- e.network.part(' '.join(e.args), requested = 'n' not in e.switches)
- else:
- raise core.events.CommandError("We're not connected.")
- elif isinstance(e.window, windows.ChannelWindow):
- e.window.network.part(e.window.id, requested = 'n' not in e.switches)
- else:
- raise core.events.CommandError("You must supply a channel.")
-
-def onCommandHop(e):
- if e.args:
- if e.network.status >= irc.INITIALIZING:
- e.network.part(e.args[0], requested = False)
- e.network.join(' '.join(e.args), requested = False)
- else:
- raise core.events.CommandError("We're not connected.")
- elif isinstance(e.window, windows.ChannelWindow):
- e.window.network.part(e.window.id, requested = False)
- e.window.network.join(e.window.id, requested = False)
- else:
- raise core.events.CommandError("You must supply a channel.")
-
-#this should be used whereever a new irc.Network may need to be created
-def server(server=None,port=6667,network=None,connect=True):
- network_info = {}
-
- if server:
- network_info["name"] = server
- network_info["server"] = server
- if port:
- network_info["port"] = port
- get_network_info(server, network_info)
-
- if not network:
- network = irc.Network(**network_info)
- windows.new(windows.StatusWindow, network, "status").activate()
- else:
- if "server" in network_info:
- network.name = network_info['name']
- network.server = network_info['server']
- if not network.status:
- #window = windows.get_default(network)
- window = core.window
- if window:
- window.update()
- if "port" in network_info:
- network.port = network_info["port"]
-
- if network.status:
- network.quit()
- if connect:
- network.connect()
- core.window.write("* Connecting to %s on port %s" % (network.server, network.port))
- #windows.get_default(network).write(
- # "* Connecting to %s on port %s" % (network.server, network.port)
- # )
-
- return network
-
-def onCommandServer(e):
- host = port = None
-
- if e.args:
- host = e.args[0]
-
- if ':' in host:
- host, port = host.rsplit(':', 1)
- port = int(port)
-
- elif len(e.args) > 1:
- port = int(e.args[1])
-
- else:
- port = 6667
-
- if 'm' in e.switches:
- network = None
- else:
- network = e.network
-
- server(server=host, port=port, network=network, connect='o' not in e.switches)
-
-#see http://www.w3.org/Addressing/draft-mirashi-url-irc-01.txt
-def onCommandIrcurl(e):
- url = e.args[0]
-
- if url.startswith('irc://'):
- url = url[6:]
-
- if not url.startswith('/'):
- host, target = url.rsplit('/',1)
- if ':' in host:
- host, port = host.rsplit(':',1)
- else:
- port = 6667
- else:
- host = None
- port = 6667
- target = url
-
- if host:
- if e.network and e.network.server == host:
- network = e.network
- else:
- for w in list(windows.manager):
- if w.network and w.network.server == host:
- network = w.network
- break
- else:
- for w in list(windows.manager):
- if w.network and w.network.server == 'irc.default.org':
- network = server(host,port,w.network)
- break
- else:
- network = server(host,port)
-
- if ',' in target:
- target, modifiers = target.split(',',1)
- action = ''
- else:
- target = unquote(target)
- if target[0] not in '#&+':
- target = '#'+target
- action = 'join %s' % target
-
- if network.status == irc.CONNECTED:
- core.events.run(action, windows.get_default(network), network)
- else:
- if not hasattr(network,'temp_perform'):
- network.temp_perform = [action]
- else:
- network.temp_perform.append(action)
-
-#commands that we need to add a : to but otherwise can send unchanged
-#the dictionary contains the number of arguments we take without adding the :
-trailing = {
- 'away':0,
- 'cnotice':2,
- 'cprivmsg':2,
- 'kick':2,
- 'kill':1,
- 'part':1,
- 'squery':1,
- 'squit':1,
- 'topic':1,
- 'wallops':0,
- }
-
-needschan = {
- 'topic':0,
- 'invite':1,
- 'kick':0,
-# 'mode':0, #this is commonly used for channels, but can apply to users
-# 'names':0, #with no parameters, this is supposed to give a list of all users; we may be able to safely ignore that.
- }
-
-def setupCommand(e):
- if not e.done:
- if e.name in needschan and isinstance(e.window, windows.ChannelWindow):
- valid_chan_prefixes = e.network.isupport.get('CHANTYPES', '#&+')
- chan_pos = needschan[e.name]
-
- if len(e.args) > chan_pos:
- if not e.args[chan_pos] or e.args[chan_pos][0] not in valid_chan_prefixes:
- e.args.insert(chan_pos, e.window.id)
- else:
- e.args.append(e.window.id)
-
- if e.name in trailing:
- trailing_pos = trailing[e.name]
-
- if len(e.args) > trailing_pos:
- e.args[trailing_pos] = ':%s' % e.args[trailing_pos]
-
- e.text = '%s %s' % (e.name, ' '.join(e.args))
-
-def setdownCommand(e):
- if not e.done and e.network.status >= irc.INITIALIZING:
- e.network.raw(e.text)
- e.done = True
-
-def get_network_info(name, network_info):
- conf_info = conf.get('networks', {}).get(name)
-
- if conf_info:
- network_info['server'] = name
- network_info.update(conf_info)
-
-def onStart(e):
- for network in conf.get('start_networks', []):
- server(server=network)
-
-def onConnect(e):
- network_info = conf.get('networks', {}).get(e.network.name, {})
-
- for command in network_info.get('perform', []):
- while command.startswith(COMMAND_PREFIX):
- command = command[len(COMMAND_PREFIX):]
- core.events.run(command, e.window, e.network)
-
- tojoin = ','.join(network_info.get('join', []))
- if tojoin:
- core.events.run('join -n %s' % tojoin, e.window, e.network)
-
- if hasattr(e.network,'temp_perform'):
- for command in e.network.temp_perform:
- core.events.run(command, e.window, e.network)
- del e.network.temp_perform
-
-def isautojoin(network, channel):
- try:
- joinlist = conf['networks'][network.name]['join']
- except KeyError:
- return False
- normchannel = network.norm_case(channel)
- for chan in joinlist:
- if normchannel == network.norm_case(chan):
- return True
- return False
-
-def setautojoin(network, channel):
- if 'networks' not in conf:
- conf['networks'] = networks = {}
- else:
- networks = conf['networks']
- if network.name not in networks:
- networks[network.name] = network_settings = {}
- if 'start_networks' not in conf:
- conf['start_networks'] = []
- conf['start_networks'].append(network.name)
- else:
- network_settings = networks[network.name]
-
- if 'join' not in network_settings:
- network_settings['join'] = [channel]
- else:
- network_settings['join'].append(channel)
-
-def unsetautojoin(network, channel):
- try:
- joinlist = conf['networks'][network.name]['join']
- except KeyError:
- return False
- normchannel = network.norm_case(channel)
- for i, chan in enumerate(joinlist[:]):
- if normchannel == network.norm_case(chan):
- joinlist.pop(i)
-
-def onChannelMenu(e):
- def toggle_join():
- if isautojoin(e.network, e.channel):
- unsetautojoin(e.network, e.channel)
- else:
- setautojoin(e.network, e.channel)
-
- e.menu.append(('Autojoin', isautojoin(e.network, e.channel), toggle_join))
diff --git a/services/console/lib/purk/scripts/keys.py b/services/console/lib/purk/scripts/keys.py
deleted file mode 100644
index e26572c..0000000
--- a/services/console/lib/purk/scripts/keys.py
+++ /dev/null
@@ -1,70 +0,0 @@
-import windows
-import widgets
-import irc
-
-shortcuts = {
- '^b': '\x02',
- '^u': '\x1F',
- '^r': '\x16',
- '^k': '\x03',
- '^l': '\x04',
- '^o': '\x0F',
- }
-
-def onKeyPress(e):
- if e.key in shortcuts:
- e.window.input.insert(shortcuts[e.key])
-
- elif e.key == '!c':
- e.window.output.copy()
-
- elif e.key == 'Page_Up':
- e.window.output.y = e.window.output.y - e.window.output.height / 2
-
- elif e.key == 'Page_Down':
- e.window.output.y = e.window.output.y + e.window.output.height / 2
-
- elif e.key == '^Home':
- e.window.output.y = 0
-
- elif e.key == '^End':
- e.window.output.y = e.window.output.ymax
-
- elif e.key in ('^Page_Up', '^Page_Down'):
- winlist = list(windows.manager)
- index = winlist.index(e.window) + ((e.key == '^Page_Down') and 1 or -1)
- if 0 <= index < len(winlist):
- winlist[index].activate()
-
- elif e.key == '!a':
- winlist = list(windows.manager)
- winlist = winlist[winlist.index(e.window):]+winlist
- w = [w for w in winlist if widgets.HILIT in w.activity]
-
- if not w:
- w = [w for w in winlist if widgets.TEXT in w.activity]
-
- if w:
- windows.manager.set_active(w[0])
-
- # tabbed browsing
- elif e.key == '^t':
- windows.new(windows.StatusWindow, irc.Network(), 'status').activate()
-
- elif e.key == '^w':
- windows.manager.get_active().close()
-
- elif e.key == '^f':
- window = windows.manager.get_active()
-
- find = widgets.FindBox(window)
-
- window.pack_start(find, expand=False)
-
- find.textbox.grab_focus()
-
- elif len(e.key) == 2 and e.key.startswith('!') and e.key[1].isdigit():
- n = int(e.key[1])
- if n and n <= len(core.manager):
- list(core.manager)[n-1].activate()
- #else e.key == "!0"
diff --git a/services/console/lib/purk/scripts/theme.py b/services/console/lib/purk/scripts/theme.py
deleted file mode 100644
index 7fda4d2..0000000
--- a/services/console/lib/purk/scripts/theme.py
+++ /dev/null
@@ -1,366 +0,0 @@
-import time
-
-import windows
-import widgets
-import chaninfo
-
-from conf import conf
-
-textareas = {}
-if 'font' in conf:
- textareas['font'] = conf['font']
-if 'bg_color' in conf:
- textareas['bg'] = conf['bg_color']
-if 'fg_color' in conf:
- textareas['fg'] = conf['fg_color']
-
-widgets.set_style("view", textareas)
-widgets.set_style("nicklist", textareas)
-
-#copied pretty directly from something that was probably copied from wine sources
-def RGBtoHSL(r, g, b):
- maxval = max(r, g, b)
- minval = min(r, g, b)
-
- luminosity = ((maxval + minval) * 240 + 255) // 510
-
- if maxval == minval:
- saturation = 0
- hue = 160
- else:
- delta = maxval - minval
-
- if luminosity <= 120:
- saturation = ((maxval+minval)//2 + delta*240) // (maxval + minval)
- else:
- saturation = ((150-maxval-minval)//2 + delta*240) // (150-maxval-minval)
-
- #sigh..
- rnorm = (delta//2 + maxval*40 - r*40)//delta
- gnorm = (delta//2 + maxval*40 - g*40)//delta
- bnorm = (delta//2 + maxval*40 - b*40)//delta
-
- if r == maxval:
- hue = bnorm-gnorm
- elif g == maxval:
- hue = 80+rnorm-bnorm
- else:
- hue = 160+gnorm-rnorm
- hue = hue % 240
- return hue, saturation, luminosity
-
-#copied from the same place
-def huetoRGB(hue, mid1, mid2):
- hue = hue % 240
-
- if hue > 160:
- return mid1
- elif hue > 120:
- hue = 160 - hue
- elif hue > 40:
- return mid2
- return ((hue * (mid2 - mid1) + 20) // 40) + mid1
-
-#this too
-def HSLtoRGB(hue, saturation, luminosity):
- if saturation != 0:
- if luminosity > 120:
- mid2 = saturation + luminosity - (saturation * luminosity + 120)//240
- else:
- mid2 = ((saturation + 240) * luminosity + 120)//240
-
- mid1 = luminosity * 2 - mid2
-
- return tuple((huetoRGB(hue+x, mid1, mid2) * 255 + 120) // 240 for x in (80,0,-80))
- else:
- value = luminosity * 255 // 240
- return value, value, value
-
-def gethashcolor(string):
- h = hash(string)
- rgb = HSLtoRGB(h%241, 100-h//241%61, 90)
- return "%02x%02x%02x" % rgb
-
-#take an event e and trigger the highlight event if necessary
-def hilight_text(e):
- if not hasattr(e, 'Highlight'):
- e.Highlight = []
- core.events.trigger('Highlight', e)
-
-#hilight own nick
-def onHighlight(e):
- lowertext = e.text.lower()
- for word in conf.get('highlight_words', []) + [e.network.me] + e.network.nicks:
- lowerword = word.lower()
- pos = lowertext.find(lowerword, 0)
- while pos != -1:
- e.Highlight.append((pos, pos+len(word)))
- pos = lowertext.find(lowerword, pos+1)
-
-def prefix(e):
- return time.strftime(conf.get('timestamp', ''))
-
-def getsourcecolor(e):
- address = getattr(e, "address", "")
- if address:
- if e.network.me == e.source:
- e.network._my_address = address
- elif e.network.me == e.source:
- address = getattr(e.network, "_my_address", "")
- if '@' in address:
- address = address.split('@')[1]
- if not address:
- address = e.source
- return "\x04%s" % gethashcolor(address)
-
-def format_source(e):
- highlight = getattr(e, "Highlight", "") and '\x02' or ''
- return "%s\x04%s%s" % (highlight, getsourcecolor(e), e.source)
-
-def format_info_source(e):
- if e.source == e.network.me:
- return "\x04%sYou" % (getsourcecolor(e))
- else:
- return "\x04%s%s" % (getsourcecolor(e), e.source)
-
-def address(e):
- #if e.source != e.network.me:
- # return "%s " % info_in_brackets(e.address)
- #else:
- # return ""
- return ""
-
-def text(e):
- if e.text:
- #return " %s" % info_in_brackets(e.text)
- return ": \x0F%s" % e.text
- else:
- return ""
-
-def info_in_brackets(text):
- return "(\x044881b6%s\x0F)" % text
-
-def pretty_time(secs):
- times = (
- #("years", "year", 31556952),
- ("weeks", "week", 604800),
- ("days", "day", 86400),
- ("hours", "hour", 3600),
- ("minutes", "minute", 60),
- ("seconds", "second", 1),
- )
- if secs == 0:
- return "0 seconds"
- result = ""
- for plural, singular, amount in times:
- n, secs = divmod(secs, amount)
- if n == 1:
- result = result + " %s %s" % (n, singular)
- elif n:
- result = result + " %s %s" % (n, plural)
- return result[1:]
-
-def onText(e):
- hilight_text(e)
- color = getsourcecolor(e)
- to_write = prefix(e)
- if e.network.me == e.target: # this is a pm
- if e.window.id == e.network.norm_case(e.source):
- to_write += "\x02<\x0F%s\x0F\x02>\x0F " % (format_source(e))
- else:
- to_write += "\x02*\x0F%s\x0F\x02*\x0F " % (format_source(e))
- else:
- if e.window.id == e.network.norm_case(e.target):
- to_write += "\x02<\x0F%s\x0F\x02>\x0F " % (format_source(e))
- else:
- to_write += "\x02<\x0F%s:%s\x0F\x02>\x0F " % (format_source(e), e.target)
- to_write += e.text
-
- if e.Highlight:
- e.window.write(to_write, widgets.HILIT)
- else:
- e.window.write(to_write, widgets.TEXT)
-
-def onOwnText(e):
- color = getsourcecolor(e)
- to_write = prefix(e)
- if e.window.id == e.network.norm_case(e.target):
- to_write += "\x02<\x0F%s\x0F\x02>\x0F %s" % (format_source(e), e.text)
- else:
- to_write += "%s->\x0F \x02*\x0F%s\x0F\x02*\x0F %s" % (color, e.target, e.text)
-
- e.window.write(to_write)
-
-def onAction(e):
- hilight_text(e)
- color = color = getsourcecolor(e)
- to_write = "%s\x02*\x0F %s\x0F %s" % (prefix(e), format_source(e), e.text)
-
- if e.Highlight:
- e.window.write(to_write, widgets.HILIT)
- else:
- e.window.write(to_write, widgets.TEXT)
-
-def onOwnAction(e):
- color = getsourcecolor(e)
- to_write = "%s\x02*\x0F %s\x0F %s" % (prefix(e), format_source(e), e.text)
-
- e.window.write(to_write)
-
-def onNotice(e):
- hilight_text(e)
- color = getsourcecolor(e)
- to_write = prefix(e)
- if e.network.me == e.target: # this is a pm
- to_write += "\x02-\x0F%s\x0F\x02-\x0F " % (format_source(e))
- else:
- to_write += "\x02-\x0F%s:%s\x0F\x02-\x0F " % (format_source(e), e.target)
- to_write += e.text
-
- e.window.write(to_write, (e.Highlight and widgets.HILIT) or widgets.TEXT)
-
-def onOwnNotice(e):
- color = getsourcecolor(e)
- to_write = "%s-> \x02-\x02%s\x0F\x02-\x0F %s" % (prefix(e), e.target, e.text)
-
- e.window.write(to_write)
-
-def onCtcp(e):
- color = getsourcecolor(e)
- to_write = "%s\x02[\x02%s\x0F\x02]\x0F %s" % (prefix(e), format_source(e), e.text)
-
- if not e.quiet:
- e.window.write(to_write)
-
-def onCtcpReply(e):
- color = getsourcecolor(e)
- to_write = "%s%s--- %s reply from %s:\x0F %s" % (prefix(e), color, e.name.capitalize(), format_source(e), ' '.join(e.args))
-
- window = windows.manager.get_active()
- if window.network != e.network:
- window = windows.get_default(e.network)
- window.write(to_write, widgets.TEXT)
-
-def onJoin(e):
- if e.source == e.network.me:
- to_write = "%s%s %sjoin %s" % (prefix(e), format_info_source(e), address(e), e.target)
- else:
- to_write = "%s%s %sjoins %s" % (prefix(e), format_info_source(e), address(e), e.target)
-
- e.window.write(to_write)
-
-def onPart(e):
- if e.source == e.network.me:
- to_write = "%s%s leave %s%s" % (prefix(e), format_info_source(e), e.target, text(e))
- else:
- to_write = "%s%s leaves %s%s" % (prefix(e), format_info_source(e), e.target, text(e))
-
- e.window.write(to_write)
-
-def onKick(e):
- if e.source == e.network.me:
- to_write = "%s%s kick %s%s" % (prefix(e), format_info_source(e), e.target, text(e))
- else:
- to_write = "%s%s kicks %s%s" % (prefix(e), format_info_source(e), e.target, text(e))
-
- e.window.write(to_write, (e.target == e.network.me and widgets.HILIT) or widgets.EVENT)
-
-def onMode(e):
- if e.source == e.network.me:
- to_write = "%s%s set mode:\x0F %s" % (prefix(e), format_info_source(e), e.text)
- else:
- to_write = "%s%s sets mode:\x0F %s" % (prefix(e), format_info_source(e), e.text)
-
- e.window.write(to_write)
-
-def onQuit(e):
- to_write = "%s%s leaves%s" % (prefix(e), format_info_source(e), text(e))
-
- for channame in chaninfo.channels(e.network):
- if chaninfo.ison(e.network, channame, e.source):
- window = windows.get(windows.ChannelWindow, e.network, channame, core)
- if window:
- window.write(to_write)
-
-def onNick(e):
- color = getsourcecolor(e)
- if e.source == e.network.me:
- to_write = "%s%sYou are now known as %s" % (prefix(e), color, e.target)
- else:
- to_write = "%s%s%s is now known as %s" % (prefix(e), color, e.source, e.target)
-
- if e.source == e.network.me:
- for window in windows.get_with(core.manager, network=e.network):
- window.write(to_write)
- else:
- for channame in chaninfo.channels(e.network):
- if chaninfo.ison(e.network,channame,e.source):
- window = windows.get(windows.ChannelWindow, e.network, channame)
- if window:
- window.write(to_write)
-
-def onTopic(e):
- if e.source == e.network.me:
- to_write = "%s%s set topic:\x0F %s" % (prefix(e), format_info_source(e), e.text)
- else:
- to_write = "%s%s sets topic:\x0F %s" % (prefix(e), format_info_source(e), e.text)
-
- e.window.write(to_write)
-
-def onRaw(e):
- if not e.quiet:
- if e.msg[1].isdigit():
- if e.msg[1] == '332':
- window = windows.get(windows.ChannelWindow, e.network, e.msg[3], core) or e.window
- window.write(
- "%sTopic on %s is: %s" %
- (prefix(e), e.msg[3], e.text)
- )
-
- elif e.msg[1] == '333':
- window = windows.get(windows.ChannelWindow, e.network, e.msg[3], core) or e.window
- window.write(
- "%sTopic on %s set by %s at time %s" %
- (prefix(e), e.msg[3], e.msg[4], time.ctime(int(e.msg[5])))
- )
-
- elif e.msg[1] == '329': #RPL_CREATIONTIME
- pass
-
- elif e.msg[1] == '311': #RPL_WHOISUSER
- e.window.write("* %s is %s@%s * %s" % (e.msg[3], e.msg[4], e.msg[5], e.msg[7]))
-
- elif e.msg[1] == '312': #RPL_WHOISSERVER
- e.window.write("* %s on %s (%s)" % (e.msg[3], e.msg[4], e.msg[5]))
-
- elif e.msg[1] == '317': #RPL_WHOISIDLE
- e.window.write("* %s has been idle for %s" % (e.msg[3], pretty_time(int(e.msg[4]))))
- if e.msg[5].isdigit():
- e.window.write("* %s signed on %s" % (e.msg[3], time.ctime(int(e.msg[5]))))
-
- elif e.msg[1] == '319': #RPL_WHOISCHANNELS
- e.window.write("* %s on channels: %s" % (e.msg[3], e.msg[4]))
-
- elif e.msg[1] == '330': #RPL_WHOISACCOUNT
- #this appears to conflict with another raw, so if there's anything weird about it,
- # we fall back on the default
- if len(e.msg) == 6 and not e.msg[4].isdigit() and not e.msg[5].isdigit():
- e.window.write("* %s %s %s" % (e.msg[3], e.msg[5], e.msg[4]))
- else:
- e.window.write("* %s" % ' '.join(e.msg[3:]))
-
- else:
- e.window.write("* %s" % ' '.join(e.msg[3:]))
- elif e.msg[1] == 'ERROR':
- e.window.write("Error: %s" % e.text)
-
-def onDisconnect(e):
- to_write = '%s* Disconnected' % prefix(e)
- if e.error:
- to_write += ' (%s)' % e.error
-
- for window in windows.get_with(network=e.network):
- if isinstance(window, windows.StatusWindow):
- window.write(to_write, widgets.TEXT)
- else:
- window.write(to_write, widgets.EVENT)
diff --git a/services/console/lib/purk/scripts/timeout.py b/services/console/lib/purk/scripts/timeout.py
deleted file mode 100755
index 2f0f585..0000000
--- a/services/console/lib/purk/scripts/timeout.py
+++ /dev/null
@@ -1,45 +0,0 @@
-import time
-
-import ui
-from conf import conf
-
-def setupRaw(e):
- e.network._message_timeout = False
-
-def onSocketConnect(e):
- timeout = conf.get("server_traffic_timeout", 120)*1000
- e.network._message_timeout = False
- if timeout:
- e.network._message_timeout_source = ui.register_timer(timeout, check_timeout, e.network)
- else:
- e.network._message_timeout_source = None
-
-def check_timeout(network):
- if network._message_timeout:
- network.raw("PING %s" % network.me)
- timeout = conf.get("server_death_timeout", 240)*1000
- network._message_timeout_source = ui.register_timer(timeout, check_death_timeout, network)
- return False
- else:
- network._message_timeout = True
- return True # call this function again
-
-def check_death_timeout(network):
- if network._message_timeout:
- network.raw("QUIT :Server missing, presumed dead")
- network.disconnect(error="The server seems to have stopped talking to us")
- else:
- network._message_timeout = False
- timeout = conf.get("server_traffic_timeout", 120)*1000
- if timeout:
- network._message_timeout_source = ui.register_timer(timeout, check_timeout, network)
- else:
- network._message_timeout_source = None
-
-def onDisconnect(e):
- try:
- if e.network._message_timeout_source:
- e.network._message_timeout_source.unregister()
- e.network._message_timeout_source = None
- except AttributeError:
- pass
diff --git a/services/console/lib/purk/scripts/ui_script.py b/services/console/lib/purk/scripts/ui_script.py
deleted file mode 100644
index 459de96..0000000
--- a/services/console/lib/purk/scripts/ui_script.py
+++ /dev/null
@@ -1,132 +0,0 @@
-import irc
-import ui
-import windows
-import irc_script
-from conf import conf
-
-# FIXME: meh still might want rid of these, I'm not sure yet
-
-def onActive(e):
- e.window.activity = None
-
- ui.register_idle(windows.manager.set_title)
-
-def setupNick(e):
- if e.source == e.network.me:
- for w in windows.get_with(core.manager, network=e.network):
- try:
- w.nick_label.update(e.target)
- except AttributeError:
- pass
-
-def onExit(e):
- for n in set(w.network for w in windows.manager):
- if n:
- n.quit()
-
-def setupJoin(e):
- if e.source == e.network.me:
- window = windows.get(windows.StatusWindow, e.network, 'status', core)
-
- if window and not conf.get('status'):
- window.mutate(windows.ChannelWindow, e.network, e.target)
- else:
- window = windows.new(windows.ChannelWindow, e.network, e.target, core)
-
- if e.requested:
- window.activate()
-
- e.window = windows.get(windows.ChannelWindow, e.network, e.target, core) or e.window
-
-def setupText(e):
- if e.target == e.network.me:
- e.window = windows.new(windows.QueryWindow, e.network, e.source, core)
- else:
- e.window = \
- windows.get(windows.ChannelWindow, e.network, e.target, core) or \
- windows.get(windows.QueryWindow, e.network, e.source, core) or \
- e.window
-
-setupAction = setupText
-
-def setupNotice(e):
- if e.target != e.network.me:
- e.window = \
- windows.get(windows.ChannelWindow, e.network, e.target, core) or e.window
-
-def setupOwnText(e):
- e.window = \
- windows.get(windows.ChannelWindow, e.network, e.target, core) or \
- windows.get(windows.QueryWindow, e.network, e.target, core) or \
- e.window
-
-setupOwnAction = setupOwnText
-
-def setdownPart(e):
- if e.source == e.network.me:
- window = windows.get(windows.ChannelWindow, e.network, e.target, core)
-
- if window:
- cwindows = list(windows.get_with(
- network=window.network,
- wclass=windows.ChannelWindow
- ))
-
- if len(cwindows) == 1 and not list(windows.get_with(network=window.network, wclass=windows.StatusWindow)):
- window.mutate(windows.StatusWindow, e.network, 'status')
- if e.requested:
- window.activate()
- elif e.requested:
- window.close()
-
-def onClose(e):
- nwindows = list(windows.get_with(core.manager, network=e.window.network))
-
- if isinstance(e.window, windows.ChannelWindow):
- cwindows = list(windows.get_with(core.manager,
- network=e.window.network,
- wclass=windows.ChannelWindow
- ))
-
- #if we only have one window for the network, don't bother to part as
- # we'll soon be quitting anyway
- if len(nwindows) != 1 and irc_script.ischan(e.window.network, e.window.id):
- e.window.network.part(e.window.id)
-
- if len(nwindows) == 1:
- core.events.trigger("CloseNetwork", window=e.window, network=e.window.network)
-
- elif isinstance(e.window, windows.StatusWindow) and conf.get('status'):
- core.events.trigger("CloseNetwork", window=e.window, network=e.window.network)
- for window in nwindows:
- if window != e.window:
- window.close()
-
- if len(core.manager) == 1:
- windows.new(windows.StatusWindow, irc.Network(), "status", core)
-
-def onConnecting(e):
- return
- window = windows.get_default(e.network)
- if window:
- window.update()
-
-onDisconnect = onConnecting
-
-def setupPart(e):
- e.window = windows.get(windows.ChannelWindow, e.network, e.target, core) or e.window
-
-setupTopic = setupPart
-
-def setupKick(e):
- e.window = windows.get(windows.ChannelWindow, e.network, e.channel, core) or e.window
-
-def setupMode(e):
- if e.target != e.network.me:
- e.window = windows.get(windows.ChannelWindow, e.network, e.target, core) or e.window
-
-def onWindowMenu(e):
- if isinstance(e.window, windows.ChannelWindow):
- e.channel = e.window.id
- e.network = e.window.network
- core.events.trigger('ChannelMenu', e)
diff --git a/services/console/lib/purk/servers.py b/services/console/lib/purk/servers.py
deleted file mode 100644
index 19ce23c..0000000
--- a/services/console/lib/purk/servers.py
+++ /dev/null
@@ -1,51 +0,0 @@
-import gtk
-
-import windows
-from conf import conf
-
-if 'networks' not in conf:
- conf['networks'] = {}
-
-def server_get_data(network_info):
- if 'port' in network_info:
- return "%s:%s" % (
- network_info.get('server', '') , network_info.get('port')
- )
- else:
- return network_info.get('server', '')
-
-def server_set_data(text, network_info):
- if ':' in text:
- network_info['server'], port = text.rsplit(':',1)
- network_info['port'] = int(port)
- else:
- network_info['server'] = text
- network_info.pop('port', None)
-
-def channels_get_data(network_info):
- return '\n'.join(network_info.get('join', ()))
-
-def channels_set_data(text, network_info):
- network_info['join'] = []
-
- for line in text.split('\n'):
- for chan in line.split(','):
- if chan:
- network_info['join'].append(chan.strip())
-
-def perform_get_data(network_info):
- return '\n'.join(network_info.get('perform', ()))
-
-def perform_set_data(text, network_info):
- network_info['perform'] = [line for line in text.split('\n') if line]
-
-def autoconnect_set_data(do_autoconnect, network):
- if 'start_networks' not in conf:
- conf['start_networks'] = []
-
- # note (n in C) != w
- if (network in conf.get('start_networks')) != do_autoconnect:
- if do_autoconnect:
- conf.get('start_networks').append(network)
- else:
- conf.get('start_networks').remove(network)
diff --git a/services/console/lib/purk/ui.py b/services/console/lib/purk/ui.py
deleted file mode 100644
index 6e1e28f..0000000
--- a/services/console/lib/purk/ui.py
+++ /dev/null
@@ -1,105 +0,0 @@
-import sys
-import os
-import thread
-import socket
-import signal
-import traceback
-
-import commands
-
-import gobject
-
-__sys_path = list(sys.path)
-import gtk
-sys.path = __sys_path
-
-import irc
-from conf import conf
-
-import widgets
-import windows
-
-# Running from same package dir
-urkpath = os.path.dirname(__file__)
-
-def path(filename=""):
- if filename:
- return os.path.join(urkpath, filename)
- else:
- return urkpath
-
-# Priority Constants
-PRIORITY_HIGH = gobject.PRIORITY_HIGH
-PRIORITY_DEFAULT = gobject.PRIORITY_DEFAULT
-PRIORITY_HIGH_IDLE = gobject.PRIORITY_HIGH_IDLE
-PRIORITY_DEFAULT_IDLE = gobject.PRIORITY_DEFAULT_IDLE
-PRIORITY_LOW = gobject.PRIORITY_LOW
-
-
-if os.access(path('profile'),os.F_OK) or os.path.expanduser("~") == "~":
- userpath = path('profile')
- if not os.access(userpath,os.F_OK):
- os.mkdir(userpath)
- if not os.access(os.path.join(userpath,'scripts'),os.F_OK):
- os.mkdir(os.path.join(userpath,'scripts'))
-else:
- userpath = os.path.join(os.path.expanduser("~"), ".urk")
- if not os.access(userpath,os.F_OK):
- os.mkdir(userpath, 0700)
- if not os.access(os.path.join(userpath,'scripts'),os.F_OK):
- os.mkdir(os.path.join(userpath,'scripts'), 0700)
-
-
-def set_clipboard(text):
- gtk.clipboard_get(gtk.gdk.SELECTION_CLIPBOARD).set_text(text)
- gtk.clipboard_get(gtk.gdk.SELECTION_PRIMARY).set_text(text)
-
-class Source(object):
- __slots__ = ['enabled']
- def __init__(self):
- self.enabled = True
- def unregister(self):
- self.enabled = False
-
-class GtkSource(object):
- __slots__ = ['tag']
- def __init__(self, tag):
- self.tag = tag
- def unregister(self):
- gobject.source_remove(self.tag)
-
-def register_idle(f, *args, **kwargs):
- priority = kwargs.pop("priority",PRIORITY_DEFAULT_IDLE)
- def callback():
- return f(*args, **kwargs)
- return GtkSource(gobject.idle_add(callback, priority=priority))
-
-def register_timer(time, f, *args, **kwargs):
- priority = kwargs.pop("priority",PRIORITY_DEFAULT_IDLE)
- def callback():
- return f(*args, **kwargs)
- return GtkSource(gobject.timeout_add(time, callback, priority=priority))
-
-def fork(cb, f, *args, **kwargs):
- is_stopped = Source()
- def thread_func():
- try:
- result, error = f(*args, **kwargs), None
- except Exception, e:
- result, error = None, e
-
- if is_stopped.enabled:
- def callback():
- if is_stopped.enabled:
- cb(result, error)
-
- gobject.idle_add(callback)
-
- thread.start_new_thread(thread_func, ())
- return is_stopped
-
-set_style = widgets.set_style
-
-def we_get_signal(*what):
- gobject.idle_add(windows.manager.exit)
-
diff --git a/services/console/lib/purk/urk_trace.py b/services/console/lib/purk/urk_trace.py
deleted file mode 100644
index 4b55b46..0000000
--- a/services/console/lib/purk/urk_trace.py
+++ /dev/null
@@ -1,70 +0,0 @@
-import sys
-import commands
-import linecache
-
-import time
-
-last_mem = [0]
-
-def traceit_memory(frame, event, arg):
- if event == "line":
- mem = int(" " + commands.getoutput(
- "ps -eo cmd,rss | grep urk_trace.py | grep -v grep"
- ).split(" ")[-1])
-
- if mem > last_mem[0]:
- last_mem[0] = mem
-
- mem = str(mem)
-
- filename = frame.f_globals["__file__"]
-
- if filename.endswith(".pyc") or filename.endswith(".pyo"):
- filename = filename[:-1]
-
- name = frame.f_globals["__name__"]
-
- lineno = frame.f_lineno
- line = linecache.getline(filename,lineno).rstrip()
-
- data = "%s:%i: %s" % (name, lineno, line)
-
- print "%s%s" % (data, mem.rjust(80 - len(data)))
-
- return traceit_memory
-
-lines = {}
-
-def traceit(frame, event, arg):
- if event == "line":
- try:
- filename = frame.f_globals["__file__"]
-
- if filename.endswith(".pyc") or filename.endswith(".pyo"):
- filename = filename[:-1]
-
- name = frame.f_globals["__name__"]
-
- lineno = frame.f_lineno
- line = linecache.getline(filename,lineno).rstrip()
-
- data = "%s:%i: %s" % (name, lineno, line)
-
- print time.time(), data
-
- #if data in lines:
- # lines[data] += 1
- #else:
- # lines[data] = 1
-
- except Exception, e:
- print e
-
- return traceit
-
-def main():
- import urk
- urk.main()
-
-sys.settrace(traceit)
-main()
diff --git a/services/console/lib/purk/widgets.py b/services/console/lib/purk/widgets.py
deleted file mode 100644
index 1ad3cb8..0000000
--- a/services/console/lib/purk/widgets.py
+++ /dev/null
@@ -1,811 +0,0 @@
-import codecs
-
-import gobject
-import gtk
-import gtk.gdk
-import pango
-
-from conf import conf
-import parse_mirc
-import windows
-
-import servers
-
-# Window activity Constants
-HILIT = 'h'
-TEXT ='t'
-EVENT = 'e'
-
-ACTIVITY_MARKUP = {
- HILIT: "<span style='italic' foreground='#00F'>%s</span>",
- TEXT: "<span foreground='#ca0000'>%s</span>",
- EVENT: "<span foreground='#363'>%s</span>",
- }
-
-# This holds all tags for all windows ever
-tag_table = gtk.TextTagTable()
-
-link_tag = gtk.TextTag('link')
-link_tag.set_property('underline', pango.UNDERLINE_SINGLE)
-
-indent_tag = gtk.TextTag('indent')
-indent_tag.set_property('indent', -20)
-
-tag_table.add(link_tag)
-tag_table.add(indent_tag)
-
-#FIXME: MEH hates dictionaries, they remind him of the bad words
-styles = {}
-
-def style_me(widget, style):
- widget.set_style(styles.get(style))
-
-def set_style(widget_name, style):
- if style:
- # FIXME: find a better way...
- dummy = gtk.Label()
- dummy.set_style(None)
-
- def apply_style_fg(value):
- dummy.modify_text(gtk.STATE_NORMAL, gtk.gdk.color_parse(value))
-
- def apply_style_bg(value):
- dummy.modify_base(gtk.STATE_NORMAL, gtk.gdk.color_parse(value))
-
- def apply_style_font(value):
- dummy.modify_font(pango.FontDescription(value))
-
- style_functions = (
- ('fg', apply_style_fg),
- ('bg', apply_style_bg),
- ('font', apply_style_font),
- )
-
- for name, f in style_functions:
- if name in style:
- f(style[name])
-
- style = dummy.rc_get_style()
- else:
- style = None
-
- styles[widget_name] = style
-
-def menu_from_list(alist):
- while alist and not alist[-1]:
- alist.pop(-1)
-
- last = None
- for item in alist:
- if item != last:
- if item:
- if len(item) == 2:
- name, function = item
-
- menuitem = gtk.ImageMenuItem(name)
-
- elif len(item) == 3:
- name, stock_id, function = item
-
- if isinstance(stock_id, bool):
- menuitem = gtk.CheckMenuItem(name)
- menuitem.set_active(stock_id)
- else:
- menuitem = gtk.ImageMenuItem(stock_id)
-
- if isinstance(function, list):
- submenu = gtk.Menu()
- for subitem in menu_from_list(function):
- submenu.append(subitem)
- menuitem.set_submenu(submenu)
-
- else:
- menuitem.connect("activate", lambda a, f: f(), function)
-
- yield menuitem
-
- else:
- yield gtk.SeparatorMenuItem()
-
- last = item
-
-class Nicklist(gtk.TreeView):
- def click(self, event):
- if event.button == 3:
- x, y = event.get_coords()
-
- (data,), path, x, y = self.get_path_at_pos(int(x), int(y))
-
- c_data = self.events.data(window=self.win, data=self[data], menu=[])
-
- self.events.trigger("ListRightClick", c_data)
-
- if c_data.menu:
- menu = gtk.Menu()
- for item in menu_from_list(c_data.menu):
- menu.append(item)
- menu.show_all()
- menu.popup(None, None, None, event.button, event.time)
-
- elif event.button == 1 and event.type == gtk.gdk._2BUTTON_PRESS:
- x, y = event.get_coords()
-
- (data,), path, x, y = self.get_path_at_pos(int(x), int(y))
-
- self.events.trigger("ListDoubleClick", window=self.win, target=self[data])
-
- def __getitem__(self, pos):
- return self.get_model()[pos][0]
-
- def __setitem__(self, pos, name_markup):
- realname, markedupname, sortkey = name_markup
-
- self.get_model()[pos] = realname, markedupname, sortkey
-
- def __len__(self):
- return len(self.get_model())
-
- def index(self, item):
- for i, x in enumerate(self):
- if x == item:
- return i
-
- return -1
-
- def append(self, realname, markedupname, sortkey):
- self.get_model().append((realname, markedupname, sortkey))
-
- def insert(self, pos, realname, markedupname, sortkey):
- self.get_model().insert(pos, (realname, markedupname, sortkey))
-
- def replace(self, names):
- self.set_model(gtk.ListStore(str, str, str))
-
- self.insert_column_with_attributes(
- 0, '', gtk.CellRendererText(), markup=1
- ).set_sizing(gtk.TREE_VIEW_COLUMN_FIXED)
-
- for name in names:
- self.append(*name)
-
- self.get_model().set_sort_column_id(2, gtk.SORT_ASCENDING)
-
- def remove(self, realname):
- index = self.index(realname)
-
- if index == -1:
- raise ValueError
-
- self.get_model().remove(self.get_model().iter_nth_child(None, index))
-
- def clear(self):
- self.get_model().clear()
-
- def __iter__(self):
- return (r[0] for r in self.get_model())
-
- def __init__(self, window, core):
- self.win = window
- self.core = core
- self.events = core.events
-
- gtk.TreeView.__init__(self)
-
- self.replace(())
-
- self.set_headers_visible(False)
- self.set_property("fixed-height-mode", True)
- self.connect("button-press-event", Nicklist.click)
- self.connect_after("button-release-event", lambda *a: True)
-
- style_me(self, "nicklist")
-
-# Label used to display/edit your current nick on a network
-class NickEditor(gtk.EventBox):
- def nick_change(self, entry):
- oldnick, newnick = self.label.get_text(), entry.get_text()
-
- if newnick and newnick != oldnick:
- self.events.run('nick %s' % newnick, self.win, self.win.network)
-
- self.win.input.grab_focus()
-
- def update(self, nick=None):
- self.label.set_text(nick or self.win.network.me)
-
- def to_edit_mode(self, widget, event):
- if self.label not in self.get_children():
- return
-
- if getattr(event, 'button', None) == 3:
- c_data = self.events.data(window=self.win, menu=[])
- self.events.trigger("NickEditMenu", c_data)
-
- if c_data.menu:
- menu = gtk.Menu()
- for item in menu_from_list(c_data.menu):
- menu.append(item)
- menu.show_all()
- menu.popup(None, None, None, event.button, event.time)
-
- else:
- entry = gtk.Entry()
- entry.set_text(self.label.get_text())
- entry.connect('activate', self.nick_change)
- entry.connect('focus-out-event', self.to_show_mode)
-
- self.remove(self.label)
- self.add(entry)
- self.window.set_cursor(None)
-
- entry.show()
- entry.grab_focus()
-
- def to_show_mode(self, widget, event):
- self.remove(widget)
- self.add(self.label)
- self.win.input.grab_focus()
- self.window.set_cursor(gtk.gdk.Cursor(gtk.gdk.XTERM))
-
- def __init__(self, window, core):
- gtk.EventBox.__init__(self)
- self.events = core.events
- self.win = window
-
- self.label = gtk.Label()
- self.label.set_padding(5, 0)
- self.add(self.label)
-
- self.connect("button-press-event", self.to_edit_mode)
-
- self.update()
-
- self.connect(
- "realize",
- lambda *a: self.window.set_cursor(gtk.gdk.Cursor(gtk.gdk.XTERM))
- )
-
-# The entry which you type in to send messages
-class TextInput(gtk.Entry):
- # Generates an input event
- def entered_text(self, ctrl):
- #for a in globals():
- # print a
- #print events.__file__
- #self.core.run_command(self.text)
- for line in self.text.splitlines():
- if line:
- e_data = self.events.data(
- window=self.win, network=self.win.network,
- text=line, ctrl=ctrl
- )
- self.events.trigger('Input', e_data)
- if not e_data.done:
- self.events.run(line, self.win, self.win.network)
-
- self.text = ''
-
- def _set_selection(self, s):
- if s:
- self.select_region(*s)
- else:
- self.select_region(self.cursor, self.cursor)
-
- #some nice toys for the scriptors
- text = property(gtk.Entry.get_text, gtk.Entry.set_text)
- cursor = property(gtk.Entry.get_position, gtk.Entry.set_position)
- selection = property(gtk.Entry.get_selection_bounds, _set_selection)
-
- def insert(self, text):
- self.do_insert_at_cursor(self, text)
-
- #hack to stop it selecting the text when we focus
- def do_grab_focus(self):
- temp = self.text, (self.selection or (self.cursor,)*2)
- self.text = ''
- gtk.Entry.do_grab_focus(self)
- self.text, self.selection = temp
-
- def keypress(self, event):
- keychar = (
- (gtk.gdk.CONTROL_MASK, '^'),
- (gtk.gdk.SHIFT_MASK, '+'),
- (gtk.gdk.MOD1_MASK, '!')
- )
-
- key = ''
- for keymod, char in keychar:
- # we make this an int, because otherwise it leaks
- if int(event.state) & keymod:
- key += char
- key += gtk.gdk.keyval_name(event.keyval)
-
- self.events.trigger('KeyPress', key=key, string=event.string, window=self.win)
-
- if key == "^Return":
- self.entered_text(True)
-
- up = gtk.gdk.keyval_from_name("Up")
- down = gtk.gdk.keyval_from_name("Down")
- tab = gtk.gdk.keyval_from_name("Tab")
-
- return event.keyval in (up, down, tab)
-
- def __init__(self, window, core):
- gtk.Entry.__init__(self)
- self.events = core.events
- self.core = core
- self.win = window
-
- # we don't want key events to propogate so we stop them in connect_after
- self.connect('key-press-event', TextInput.keypress)
- self.connect_after('key-press-event', lambda *a: True)
-
- self.connect('activate', TextInput.entered_text, False)
-
-gobject.type_register(TextInput)
-
-def prop_to_gtk(textview, (prop, val)):
- if val == parse_mirc.BOLD:
- val = pango.WEIGHT_BOLD
-
- elif val == parse_mirc.UNDERLINE:
- val = pango.UNDERLINE_SINGLE
-
- return {prop: val}
-
-def word_from_pos(text, pos):
- if text[pos] == ' ':
- return ' ', pos, pos+1
-
- else:
- fr = text[:pos].split(" ")[-1]
- to = text[pos:].split(" ")[0]
-
- return fr + to, pos - len(fr), pos + len(to)
-
-def get_iter_at_coords(view, x, y):
- return view.get_iter_at_location(
- *view.window_to_buffer_coords(gtk.TEXT_WINDOW_TEXT, int(x), int(y))
- )
-
-def get_event_at_iter(view, iter, core):
- buffer = view.get_buffer()
-
- line_strt = buffer.get_iter_at_line(iter.get_line())
- line_end = line_strt.copy()
- line_end.forward_lines(1)
-
- pos = iter.get_line_offset()
-
- #Caveat: text must be a unicode string, not utf-8 encoded; otherwise our
- # offsets will be off when we use anything outside 7-bit ascii
- #gtk.TextIter.get_text returns unicode but gtk.TextBuffer.get_text does not
- text = line_strt.get_text(line_end).rstrip("\n")
-
- word, fr, to = word_from_pos(text, pos)
-
- return core.events.data(
- window=view.win, pos=pos, text=text,
- target=word, target_fr=fr, target_to=to,
- )
-
-class TextOutput(gtk.TextView):
- def copy(self):
- startend = self.get_buffer().get_selection_bounds()
-
- tagsandtext = []
- if startend:
- start, end = startend
-
- while not start.equal(end):
- tags_at_iter = {}
- for tag in start.get_tags():
- try:
- tagname, tagval = eval(tag.get_property('name'))
- tags_at_iter[tagname] = tagval
- except NameError:
- continue
-
- tagsandtext.append((dict(tags_at_iter), start.get_char()))
- start.forward_char()
-
- text = parse_mirc.unparse_mirc(tagsandtext)
-
- gtk.clipboard_get(gtk.gdk.SELECTION_CLIPBOARD).set_text(text)
- gtk.clipboard_get(gtk.gdk.SELECTION_PRIMARY).set_text(text)
-
- return text
-
- def clear(self):
- self.get_buffer().set_text('')
-
- def get_y(self):
- rect = self.get_visible_rect()
- return rect.y
-
- def set_y(self,y):
- iter = self.get_iter_at_location(0, y)
- if self.get_iter_location(iter).y < y:
- self.forward_display_line(iter)
- yalign = float(self.get_iter_location(iter).y-y)/self.height
- self.scroll_to_iter(iter, 0, True, 0, yalign)
-
- self.check_autoscroll()
-
- def get_ymax(self):
- buffer = self.get_buffer()
- return sum(self.get_line_yrange(buffer.get_end_iter())) - self.height
-
- def get_height(self):
- return self.get_visible_rect().height
-
- y = property(get_y, set_y)
- ymax = property(get_ymax)
- height = property(get_height)
-
- # the unknowing print weird things to our text widget function
- def write(self, text, line_ending='\n', fg=None):
- if not isinstance(text, unicode):
- try:
- text = codecs.utf_8_decode(text)[0]
- except:
- text = codecs.latin_1_decode(text)[0]
- tags, text = parse_mirc.parse_mirc(text)
-
- if fg:
- tags.append({'data': ("foreground", isinstance(fg, basestring) and ('#%s'%fg) or parse_mirc.get_mirc_color(fg)), 'from': 0, 'to': len(text)})
-
- buffer = self.get_buffer()
-
- cc = buffer.get_char_count()
-
- buffer.insert_with_tags_by_name(
- buffer.get_end_iter(),
- text + line_ending,
- 'indent'
- )
-
- for tag in tags:
- tag_name = str(tag['data'])
-
- if not tag_table.lookup(tag_name):
- buffer.create_tag(tag_name, **prop_to_gtk(self, tag['data']))
-
- buffer.apply_tag_by_name(
- tag_name,
- buffer.get_iter_at_offset(tag['from'] + cc),
- buffer.get_iter_at_offset(tag['to'] + cc)
- )
-
- def popup(self, menu):
- hover_iter = get_iter_at_coords(self, *self.hover_coords)
-
- menuitems = []
- if not hover_iter.ends_line():
- c_data = get_event_at_iter(self, hover_iter)
- c_data.menu = []
-
- self.events.trigger("RightClick", c_data)
-
- menuitems = c_data.menu
-
- if not menuitems:
- c_data = self.events.data(menu=[])
- self.events.trigger("MainMenu", c_data)
-
- menuitems = c_data.menu
-
- for child in menu.get_children():
- menu.remove(child)
-
- for item in menu_from_list(menuitems):
- menu.append(item)
-
- menu.show_all()
-
- def mousedown(self, event):
- if event.button == 3:
- self.hover_coords = event.get_coords()
-
- def mouseup(self, event):
- if not self.get_buffer().get_selection_bounds():
- if event.button == 1:
- hover_iter = get_iter_at_coords(self, event.x, event.y)
-
- if not hover_iter.ends_line():
- c_data = get_event_at_iter(self, hover_iter, self.core)
-
- self.events.trigger("Click", c_data)
-
- if self.is_focus():
- self.win.focus()
-
- def clear_hover(self, _event=None):
- buffer = self.get_buffer()
-
- for fr, to in self.linking:
- buffer.remove_tag_by_name(
- "link",
- buffer.get_iter_at_mark(fr),
- buffer.get_iter_at_mark(to)
- )
-
- self.linking = set()
- self.get_window(gtk.TEXT_WINDOW_TEXT).set_cursor(None)
-
- def hover(self, event):
- if self.linking:
- self.clear_hover()
-
- hover_iter = get_iter_at_coords(self, event.x, event.y)
-
- if not hover_iter.ends_line():
- h_data = get_event_at_iter(self, hover_iter, self.core)
- h_data.tolink = set()
-
- self.events.trigger("Hover", h_data)
-
- if h_data.tolink:
- buffer = self.get_buffer()
-
- offset = buffer.get_iter_at_line(
- hover_iter.get_line()
- ).get_offset()
-
- for fr, to in h_data.tolink:
- fr = buffer.get_iter_at_offset(offset + fr)
- to = buffer.get_iter_at_offset(offset + to)
-
- buffer.apply_tag_by_name("link", fr, to)
-
- self.linking.add(
- (buffer.create_mark(None, fr),
- buffer.create_mark(None, to))
- )
-
- self.get_window(
- gtk.TEXT_WINDOW_TEXT
- ).set_cursor(gtk.gdk.Cursor(gtk.gdk.HAND2))
-
- self.get_pointer()
-
- def scroll(self, _allocation=None):
- if self.autoscroll:
- def do_scroll():
- self.scroller.value = self.scroller.upper - self.scroller.page_size
- self._scrolling = False
-
- if not self._scrolling:
- self._scrolling = gobject.idle_add(do_scroll)
-
- def check_autoscroll(self, *args):
- def set_to_scroll():
- self.autoscroll = self.scroller.value + self.scroller.page_size >= self.scroller.upper
-
- gobject.idle_add(set_to_scroll)
-
- def __init__(self, core, window, buffer=None):
- if not buffer:
- buffer = gtk.TextBuffer(tag_table)
-
- gtk.TextView.__init__(self, buffer)
- self.core = core
- self.events = core.events
- self.win = window
-
- self.set_size_request(0, -1)
-
- self.set_wrap_mode(gtk.WRAP_WORD_CHAR)
- self.set_editable(False)
- self.set_cursor_visible(False)
-
- self.set_property("left-margin", 3)
- self.set_property("right-margin", 3)
-
- self.linking = set()
-
- self.add_events(gtk.gdk.POINTER_MOTION_HINT_MASK)
- self.add_events(gtk.gdk.LEAVE_NOTIFY_MASK)
-
- self.connect('populate-popup', TextOutput.popup)
- self.connect('motion-notify-event', TextOutput.hover)
- self.connect('button-press-event', TextOutput.mousedown)
- self.connect('button-release-event', TextOutput.mouseup)
- self.connect_after('button-release-event', lambda *a: True)
- self.connect('leave-notify-event', TextOutput.clear_hover)
-
- self.hover_coords = 0, 0
-
- self.autoscroll = True
- self._scrolling = False
- self.scroller = gtk.Adjustment()
-
- def setup_scroll(self, _adj, vadj):
- self.scroller = vadj
-
- if vadj:
- def set_scroll(adj):
- self.autoscroll = adj.value + adj.page_size >= adj.upper
-
- vadj.connect("value-changed", set_scroll)
-
- self.connect("set-scroll-adjustments", setup_scroll)
- self.connect("size-allocate", TextOutput.scroll)
-
- def set_cursor(widget):
- self.get_window(gtk.TEXT_WINDOW_TEXT).set_cursor(None)
-
- self.connect("realize", set_cursor)
-
- style_me(self, "view")
-
-class WindowLabel(gtk.EventBox):
- def update(self):
- title = self.win.get_title()
-
- for escapes in (('&','&amp;'), ('<','&lt;'), ('>','&gt;')):
- title = title.replace(*escapes)
-
- for a_type in (HILIT, TEXT, EVENT):
- if a_type in self.win.activity:
- title = ACTIVITY_MARKUP[a_type] % title
- break
-
- self.label.set_markup(title)
-
- def tab_popup(self, event):
- if event.button == 3: # right click
- c_data = self.events.data(window=self.win, menu=[])
- self.events.trigger("WindowMenu", c_data)
-
- c_data.menu += [
- None,
- ("Close", gtk.STOCK_CLOSE, self.win.close),
- ]
-
- menu = gtk.Menu()
- for item in menu_from_list(c_data.menu):
- menu.append(item)
- menu.show_all()
- menu.popup(None, None, None, event.button, event.time)
-
- def __init__(self, window, core):
- gtk.EventBox.__init__(self)
- self.core = core
- self.events = core.events
-
- self.win = window
- self.connect("button-press-event", WindowLabel.tab_popup)
-
- self.label = gtk.Label()
- self.add(self.label)
-
- self.update()
- self.show_all()
-
-class FindBox(gtk.HBox):
- def remove(self, *args):
- self.parent.remove(self)
- self.win.focus()
-
- def clicked(self, button, search_down=False):
- text = self.textbox.get_text()
-
- if not text:
- return
-
- buffer = self.win.output.get_buffer()
-
- if buffer.get_selection_bounds():
- if button == self.down:
- _, cursor_iter = buffer.get_selection_bounds()
- else:
- cursor_iter, _ = buffer.get_selection_bounds()
- else:
- cursor_iter = buffer.get_end_iter()
-
- if search_down:
- cursor = cursor_iter.forward_search(
- text, gtk.TEXT_SEARCH_VISIBLE_ONLY
- )
- else:
- cursor = cursor_iter.backward_search(
- text, gtk.TEXT_SEARCH_VISIBLE_ONLY
- )
-
- if not cursor:
- return
-
- fr, to = cursor
-
- if button == self.up:
- buffer.place_cursor(fr)
- self.win.output.scroll_to_iter(fr, 0)
- elif button == self.down:
- buffer.place_cursor(to)
- self.win.output.scroll_to_iter(to, 0)
-
- buffer.select_range(*cursor)
-
- cursor_iter = buffer.get_iter_at_mark(buffer.get_insert())
-
- def __init__(self, window):
- gtk.HBox.__init__(self)
-
- self.win = window
-
- self.up = gtk.Button(stock='gtk-go-up')
- self.down = gtk.Button(stock='gtk-go-down')
-
- self.up.connect('clicked', self.clicked)
- self.down.connect('clicked', self.clicked, True)
-
- self.up.set_property('can_focus', False)
- self.down.set_property('can_focus', False)
-
- self.textbox = gtk.Entry()
-
- self.textbox.connect('focus-out-event', self.remove)
- self.textbox.connect('activate', self.clicked)
-
- self.pack_start(gtk.Label('Find:'), expand=False)
- self.pack_start(self.textbox)
-
- self.pack_start(self.up, expand=False)
- self.pack_start(self.down, expand=False)
-
- self.show_all()
-
-#class UrkUITabs(gtk.Window):
-class UrkUITabs(object):
- def __init__(self, core):
- # threading stuff
- gtk.gdk.threads_init()
- self.core = core
- self.events = core.events
- self.tabs = gtk.Notebook()
- self.tabs.set_property(
- "tab-pos",
- conf.get("ui-gtk/tab-pos", gtk.POS_BOTTOM)
- )
-
- self.tabs.set_scrollable(True)
- self.tabs.set_property("can-focus", False)
-
- self.box = gtk.VBox(False)
- self.box.pack_end(self.tabs)
-
- def __iter__(self):
- return iter(self.tabs.get_children())
-
- def __len__(self):
- return self.tabs.get_n_pages()
-
- def exit(self, *args):
- self.events.trigger("Exit")
- gtk.main_level() and gtk.main_quit()
-
- def get_active(self):
- return self.tabs.get_nth_page(self.tabs.get_current_page())
-
- def set_active(self, window):
- self.tabs.set_current_page(self.tabs.page_num(window))
-
- def add(self, window):
- for pos in reversed(range(self.tabs.get_n_pages())):
- if self.tabs.get_nth_page(pos).network == window.network:
- break
- else:
- pos = self.tabs.get_n_pages() - 1
-
- self.tabs.insert_page(window, WindowLabel(window, self.core), pos+1)
-
- def remove(self, window):
- self.tabs.remove_page(self.tabs.page_num(window))
-
- def update(self, window):
- self.tabs.get_tab_label(window).update()
-
- def show_all(self):
- self.box.show_all()
diff --git a/services/console/lib/purk/windows.py b/services/console/lib/purk/windows.py
deleted file mode 100644
index 22c783a..0000000
--- a/services/console/lib/purk/windows.py
+++ /dev/null
@@ -1,298 +0,0 @@
-import gtk
-
-import irc
-from conf import conf
-import widgets
-
-#manager = widgets.UrkUITabs()
-
-def append(window, manager):
- manager.add(window)
-
-def remove(window, manager):
- manager.remove(window)
-
- # i don't want to have to call this
- window.destroy()
-
-def new(wclass, network, id, core):
- if network is None:
- network = irc.dummy_network
-
- w = get(wclass, network, id, core)
- if not w:
- w = wclass(network, id, core)
- append(w, core.manager)
-
- return w
-
-def get(windowclass, network, id, core):
- if network:
- id = network.norm_case(id)
-
- for w in core.manager:
- if (type(w), w.network, w.id) == (windowclass, network, id):
- return w
-
-def get_with(manager, wclass=None, network=None, id=None):
- if network and id:
- id = network.norm_case(id)
-
- for w in list(manager):
- for to_find, found in ((wclass, type(w)), (network, w.network), (id, w.id)):
- # to_find might be False but not None (if it's a DummyNetwork)
- if to_find is not None and to_find != found:
- break
- else:
- yield w
-
-def get_default(network, manager):
-
- window = manager.get_active()
- if window.network == network:
- return window
-
- # There can be only one...
- for window in get_with(network=network):
- return window
-
-class Window(gtk.VBox):
- need_vbox_init = True
-
- def mutate(self, newclass, network, id):
- isactive = self == manager.get_active()
- self.hide()
-
- for child in self.get_children():
- self.remove(child)
-
- self.__class__ = newclass
- self.__init__(network, id)
- self.update()
- if isactive:
- self.activate()
-
- def transfer_text(self, _widget, event):
- if event.string and not self.input.is_focus():
- self.input.grab_focus()
- self.input.set_position(-1)
- self.input.event(event)
-
- def write(self, text, activity_type=widgets.EVENT, line_ending='\n', fg=None):
- if self.manager.get_active() != self:
- self.activity = activity_type
- self.output.write(text, line_ending, fg)
-
- def get_id(self):
- if self.network:
- return self.network.norm_case(self.rawid)
- else:
- return self.rawid
-
- def set_id(self, id):
- self.rawid = id
- self.update()
-
- id = property(get_id, set_id)
-
- def get_toplevel_title(self):
- return self.rawid
-
- def get_title(self):
- return self.rawid
-
- def get_activity(self):
- return self.__activity
-
- def set_activity(self, value):
- if value:
- self.__activity.add(value)
- else:
- self.__activity = set()
- self.update()
-
- activity = property(get_activity, set_activity)
-
- def focus(self):
- pass
-
- def activate(self):
- self.manager.set_active(self)
- self.focus()
-
- def close(self):
- self.events.trigger("Close", window=self)
- remove(self, self.manager)
-
- def update(self):
- self.manager.update(self)
-
- def __init__(self, network, id, core):
- self.manager = core.manager
- self.events = core.events
-
- if self.need_vbox_init:
- #make sure we don't call this an extra time when mutating
- gtk.VBox.__init__(self, False)
- self.need_vbox_init = False
-
- if hasattr(self, "buffer"):
- self.output = widgets.TextOutput(core, self, self.buffer)
- else:
- self.output = widgets.TextOutput(core, self)
- self.buffer = self.output.get_buffer()
-
- if hasattr(self, "input"):
- if self.input.parent:
- self.input.parent.remove(self.input)
- else:
- self.input = widgets.TextInput(self, core)
-
- self.network = network
- self.rawid = id
-
- self.__activity = set()
-
-class SimpleWindow(Window):
- def __init__(self, network, id, core):
- Window.__init__(self, network, id)
-
- self.focus = self.input.grab_focus
- self.connect("key-press-event", self.transfer_text)
-
- self.pack_end(self.input, expand=False)
-
- topbox = gtk.ScrolledWindow()
- topbox.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)
- topbox.add(self.output)
-
- self.pack_end(topbox)
-
- self.show_all()
-
-class StatusWindow(Window):
- def get_toplevel_title(self):
- return '%s - %s' % (self.network.me, self.get_title())
-
- def get_title(self):
- # Something about self.network.isupport
- if self.network.status:
- return "%s" % self.network.server
- else:
- return "[%s]" % self.network.server
-
- def __init__(self, network, id, core):
- Window.__init__(self, network, id, core)
-
- self.nick_label = widgets.NickEditor(self, core)
-
- self.focus = self.input.grab_focus
- self.connect("key-press-event", self.transfer_text)
- self.manager = core.manager
- botbox = gtk.HBox()
- botbox.pack_start(self.input)
- botbox.pack_end(self.nick_label, expand=False)
-
- self.pack_end(botbox, expand=False)
-
- topbox = gtk.ScrolledWindow()
- topbox.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)
- topbox.add(self.output)
-
- self.pack_end(topbox)
-
- self.show_all()
-
-class QueryWindow(Window):
- def __init__(self, network, id, core):
- Window.__init__(self, network, id, core)
-
- self.nick_label = widgets.NickEditor(self, core)
-
- self.focus = self.input.grab_focus
- self.connect("key-press-event", self.transfer_text)
-
- botbox = gtk.HBox()
- botbox.pack_start(self.input)
- botbox.pack_end(self.nick_label, expand=False)
-
- self.pack_end(botbox, expand=False)
-
- topbox = gtk.ScrolledWindow()
- topbox.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)
- topbox.add(self.output)
-
- self.pack_end(topbox)
-
- self.show_all()
-
-def move_nicklist(paned, event):
- paned._moving = (
- event.type == gtk.gdk._2BUTTON_PRESS,
- paned.get_position()
- )
-
-def drop_nicklist(paned, event):
- width = paned.allocation.width
- pos = paned.get_position()
-
- double_click, nicklist_pos = paned._moving
-
- if double_click:
- # if we're "hidden", then we want to unhide
- if width - pos <= 10:
- # get the normal nicklist width
- conf_nicklist = conf.get("ui-gtk/nicklist-width", 200)
-
- # if the normal nicklist width is "hidden", then ignore it
- if conf_nicklist <= 10:
- paned.set_position(width - 200)
- else:
- paned.set_position(width - conf_nicklist)
-
- # else we hide
- else:
- paned.set_position(width)
-
- else:
- if pos != nicklist_pos:
- conf["ui-gtk/nicklist-width"] = width - pos - 6
-
-class ChannelWindow(Window):
- def __init__(self, network, id, core):
- Window.__init__(self, network, id, core)
-
- self.nicklist = widgets.Nicklist(self, core)
- self.nick_label = widgets.NickEditor(self, core)
-
- self.focus = self.input.grab_focus
- self.connect("key-press-event", self.transfer_text)
-
- topbox = gtk.ScrolledWindow()
- topbox.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)
- topbox.add(self.output)
-
- nlbox = gtk.ScrolledWindow()
- nlbox.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)
- nlbox.add(self.nicklist)
-
- nlbox.set_size_request(conf.get("ui-gtk/nicklist-width", 112), -1)
-
- botbox = gtk.HBox()
- botbox.pack_start(self.input)
- botbox.pack_end(self.nick_label, expand=False)
-
- self.pack_end(botbox, expand=False)
-
- pane = gtk.HPaned()
- pane.pack1(topbox, resize=True, shrink=False)
- pane.pack2(nlbox, resize=False, shrink=True)
-
- self.nicklist.pos = None
-
- pane.connect("button-press-event", move_nicklist)
- pane.connect("button-release-event", drop_nicklist)
-
- self.pack_end(pane)
-
- self.show_all()