├── .gitignore
├── CHANGES.txt
├── README.txt
├── TODO.txt
├── docs
└── vision.html
├── howie.ini
├── howie.nsi
├── howie
├── __init__.py
├── aiml
│ ├── AimlParser.py
│ ├── DefaultSubs.py
│ ├── Kernel.py
│ ├── PatternMgr.py
│ ├── Utils.py
│ ├── WordSub.py
│ ├── __init__.py
│ └── self-test.aiml
├── configFile.py
├── core.py
└── frontends
│ ├── __init__.py
│ ├── aim.py
│ ├── frontend.py
│ ├── icq.py
│ ├── irc.py
│ ├── ircbot.py
│ ├── irclib.py
│ ├── jabber.py
│ ├── msn.py
│ ├── msnp
│ ├── __init__.py
│ ├── chat.py
│ ├── codec.py
│ ├── command.py
│ ├── error.py
│ ├── friend.py
│ ├── net.py
│ ├── protocol.py
│ └── session.py
│ ├── oscarlistener.py
│ ├── tty.py
│ ├── xmlrpc.py
│ └── xmpp
│ ├── __init__.py
│ ├── auth.py
│ ├── browser.py
│ ├── client.py
│ ├── debug.py
│ ├── dispatcher.py
│ ├── features.py
│ ├── filetransfer.py
│ ├── protocol.py
│ ├── roster.py
│ ├── session.py
│ ├── simplexml.py
│ └── transports.py
├── make_win32_installer.bat
├── my-howie.aiml
├── runme.py
├── scripts
├── acronym.py
├── echo.py
├── googlism.py
├── multiple.db
├── rhyme.py
├── rhymes.db
└── words.db
├── setup.cfg
├── setup.py
├── standard
├── _readme.txt
├── dev-calendar.aiml
├── dev-examples.aiml
├── dev-scripts.aiml
├── dev-testcases.aiml
├── dev-translation.aiml
├── dev-webhelper.aiml
├── howie-acronym.aiml
├── howie-googlism.aiml
├── howie-rhyme.aiml
├── per-drWallace.aiml
├── startup.xml
├── std-65percent.aiml
├── std-atomic.aiml
├── std-botmaster.aiml
├── std-brain.aiml
├── std-connect.aiml
├── std-dictionary.aiml
├── std-disconnect.aiml
├── std-dont.aiml
├── std-errors.aiml
├── std-gender.aiml
├── std-geography.aiml
├── std-german.aiml
├── std-gossip.aiml
├── std-hello.aiml
├── std-inactivity.aiml
├── std-inventions.aiml
├── std-knowledge.aiml
├── std-lizards.aiml
├── std-login.aiml
├── std-numbers.aiml
├── std-personality.aiml
├── std-pickup.aiml
├── std-politics.aiml
├── std-profile.aiml
├── std-religion.aiml
├── std-robot.aiml
├── std-sales.aiml
├── std-sextalk.aiml
├── std-sports.aiml
├── std-srai.aiml
├── std-suffixes.aiml
├── std-that.aiml
├── std-turing.aiml
└── std-yesno.aiml
├── std-startup.xml
└── unix-install.py
/.gitignore:
--------------------------------------------------------------------------------
1 | *.pyc
2 |
--------------------------------------------------------------------------------
/CHANGES.txt:
--------------------------------------------------------------------------------
1 | - SF Bug #1050427: Howie now reliably disconnects and quits when you give him
2 | a control-C.
3 | - Upgraded to PyAIML version 0.8.5. This version includes standards-compliant
4 | whitespace handling, and fixes a handful of Unicode and crash bugs.
5 | - AIM/ICQ: Updated for compatibility with Twisted 2.2.0 (removed some deprecation warnings).
6 | - JABBER: Upgraded to xmpppy 0.3.1.
7 | - JABBER: Removed hard-coded port number, and put it in howie.ini instead.
8 |
9 | 0.6.0:
10 | - Upgraded to PyAIML version 0.8.4. This version includes support for
11 | multiple wildcards in AIML patterns, the "index" attribute of the "star"
12 | AIML elements, and Unicode input and AIML files.
13 | - Improved error-handling during front-end module initialization. Previously,
14 | any errors were mistakenly reported as "could not find valid frontend class"
15 | warnings.
16 | - AIM: Replaced broken PyTOC module with Twisted's OSCAR module.
17 | - ICQ: Added support for the ICQ protocol.
18 | - IRC: Added support for the IRC protocol (courtesy of Jamie Turner).
19 | - JABBER: Modified jabber back-end to use the xmpppy package, instead of the
20 | apparently-defunct jabber.py.
21 | - MSN: Applied patch to msnp module to fix problem with redirect messages
22 | while logging in.
23 | - MSN: Fixed bug in msnp's __process_add() function.
24 | - MSN: Fixed bug in MSN frontend's friend-adding code.
25 | - XMLRPC: Wrapped call to register_introspection_functions() to allow it to
26 | run without crashing older versions of Python.
27 |
28 |
29 | 0.5.0:
30 | - Arbitrary switch from date-based snapshots to "real" version numbers
31 | - Upgraded AIML interpreter to PyAIML version 0.8.2. This release fixes some
32 | crashes involving infinite AIML recursion and passing Unicode strings as
33 | input to the bot.
34 | - Upgraded to MSNP 0.4.1. The MSN front-end is now working! I'll continue to
35 | improve it in future releases, but it should be quite usable for now.
36 | - Added Jabber chat front-end (based on jabber.py by Matthew Allum).
37 | - Added new "botinfo" section to the config file, used to customize your bot's
38 | personality. Any entries added to this section are used to set up the
39 | bot predicates (accessed through the AIML element).
40 |
41 | 1/10/2004:
42 | - Upgraded AIML interpreter to PyAIML version 0.8.1. Fixes a problem with
43 | "system" tags written for Windows not working on UNIX, and vice versa. For
44 | cross-platform compatibility, all "system" tags should use UNIX-style
45 | pathnames (e.g. "path/to/script").
46 | - Added "unix-install.py" helper script to automate some necessary setup
47 | steps on UNIX platforms.
48 | - Removed some Python 2.3-specific features; Howie should now run on Python
49 | 2.2.x.
50 | - Howie now prompts for screenname/password at startup if the values aren't
51 | specified in the config file (useful for those who don't like leaving
52 | passwords lying around in plaintext on disk).
53 | - Reorganized and commented configuration file.
54 |
55 | 1/9/2004:
56 | - Upgraded AIML interpreter to PyAIML version 0.8.
57 | - Upgraded msnp package to v0.4.0 (the frontend still doesn't work, though).
58 | - Added XMLRPC front-end.
59 | - Added support for "what does X stand for" questions (acronym expansion).
60 | - Added support for persistent session data (so Howie remembers the people
61 | he's talked to even after he's rebooted). To enable, set "sessionspersist"
62 | to "yes" in howie.ini.
63 |
64 | 12/17/2003:
65 | - New pure-Python AIML interpreter (out with J-Alice, in with PyAIML,
66 | version 0.5).
67 | - Fixed minor bugs in Googlism code.
68 | - Added some missing tags in AIML files.
69 | - Bot name and verbosity are now initialized from the config file.
70 | - Added support for conversation logging (enabled in the config file).
71 | - Howie can now answer "what rhymes with X?" questions.
72 | - Installer now lets you customize which optional extension modules are
73 | installed.
74 |
75 | 12/1/2003: "Apocalypse Howie (Dev-20031201) is released
76 | - Fixed bug in front-end loader that required a bunch of otherwise
77 | unnecessary Python scripts to be included with a binary installation.
78 | - Fixed broken sync-mode tags on Win32 builds! This is huge --
79 | sync-mode tags will be the keystone of Howie's future
80 | functionality.
81 | - Added a "scripts" directory, as a repository for the add-on commands
82 | that Howie will run from inside tags.
83 | - Added a "my-howie.aiml" file for users to fill with their own custom AIML
84 | responses.
85 | - Moved Googlisms back-end into a stand-alone Python script, triggered through
86 | AIML using a sync-mode tag. This is the future!
87 |
88 | 11/21/2003: "Return of the Howie Extended Edition" (Dev-20031121) is released
89 | - Windows binary distribution is now a self-contained executable.
90 | On Windows systems, Python is no longer required to run Howie.
91 | - Added documentation folder, mostly pertaining to compiling the sources.
92 |
93 | 11/19/2003: "Return Of The Howie" (Dev-20031119) is released
94 | - Updated J-Alice to version 0.5. See the J-Alice homepage for summary
95 | of new features.
96 |
97 | 5/30/2003: "Finding Howie" (Dev-20030530) is released
98 | - Fixed J-Alice bug which caused Howie to repeat his first response
99 | over and over.
100 | - Massive code reorganization makes adding new frontends a breeze!
101 | - Connection parameters are read from the new configuration file,
102 | howie.ini.
103 | - Added command-line interface (force command-line only with the -l flag).
104 |
105 | 5/15/2003: "Howie Reloaded" (Dev-20030515) is released
106 | - initial pre-pre-alpha version, Windows installer only.
107 | - AIM only
108 |
--------------------------------------------------------------------------------
/README.txt:
--------------------------------------------------------------------------------
1 | Howie - A Conversational AI Bot
2 | (http://howie.sourceforge.net/)
3 | Copyright (C) 2003-2004 Cort Stratton (cortATcortstrattonDOTorg)
4 |
5 | ABOUT HOWIE
6 | -----------
7 | Howie is a conversational AI -- a computer program you can talk to. He
8 | is designed to be simple to install, configure and (above all) extend.
9 |
10 | Howie is Friendly.
11 | Currently, Howie is willing to discuss religion, sports, sex (reluctantly),
12 | and philosophy. He even knows a little German!
13 |
14 | Howie is Helpful.
15 | Howie is able to answer most questions of the form "Who/what/where/when
16 | is/was/are/were X?" -- though his answers are occasionally more
17 | entertaining than accurate. He can also help find rhymes for a word, or
18 | tell you what an acronym means. He will someday provide definitions or
19 | synonyms for any word in the dictionary, query your address book, and even
20 | perform a few simple remote system-administration tasks!
21 |
22 | Howie is Connected.
23 | You can communicate with Howie in a number of different ways: AIM, ICQ, IRC, MSN
24 | Messenger, Jabber Chat, XML-RPC, or locally on the command-line. Future
25 | versions will include interfaces for HTTP, Zephyr, and more!
26 | Howie's knowledge base is made up of a wide variety of Internet resources.
27 | If you find something that he can't do, it's usually pretty
28 | straightforward to teach him!
29 |
30 | SYSTEM REQUIREMENTS
31 | -------------------
32 | Howie has been tested on Windows XP, Red Hat Linux and NetBSD. However,
33 | he should work on any system that meets the following requirements:
34 | - Python 2.2.x or greater.
35 | - 64 MB available RAM (depending on the AIML set you're using)
36 | - Dedicated Internet connection
37 | - The Twisted framework, version 2.2.0 or later (http://twistedmatrix.com/products/twisted).
38 | You must have Twisted installed in order to run Howie from the source.
39 | NOTE: The Windows binary distribution already includes Twisted.
40 |
41 | NOTE: There is a known problem with Howie running under Windows 95, having
42 | to do with Python's os.popen() function not working on that platform.
43 |
44 | INSTALLATION (Windows binary distribution)
45 | ------------------------------------------
46 | 1. Run the installer (you've done that).
47 | 2. Edit the howie.ini file, found in the directory where you installed Howie.
48 | (You can access this file through the "Howie->Configure Howie" shortcut in
49 | your Start Menu). This file lets you set up the interfaces presented to
50 | visitors (AIM, MSN, etc.) as well as customize Howie's behavior. Each
51 | section has an "active" parameter, which indicates whether that module is
52 | active ("yes") or not.
53 | 3. To test Howie in local-mode (text console interface only), use the
54 | "Howie->Run Howie (local)" shortcut in your Start Menu. This will let you
55 | chat with Howie without opening any connections to the Internet.
56 | 4. Once you're satisfied with your setup, run the "Howie->Run Howie" shortcut,
57 | found in your Start Menu. This launches Howie and makes him available to
58 | world at large!
59 |
60 | INSTALLATION (Source distribution)
61 | ----------------------------------
62 | 1. Unzip the archive (you've done that).
63 | 2. UNIX USERS: run the "unix-install.py" script found in the main Howie
64 | directory (run "python unix-install.py" from the main Howie directory).
65 | It will automatically configure Howie to run in a UNIX-like environment.
66 | 3. Edit the howie.ini file, found in the directory where you installed Howie.
67 | This file lets you set up the interfaces presented to visitors (AIM, MSN,
68 | etc.) as well as customize Howie's behavior. Each section has an "active"
69 | parameter, which indicates whether that module is active ("yes") or not.
70 | 4. To test Howie locally, run "runme.py -l" in the main Howie directory.
71 | This lets you chat with Howie without activating any of his network
72 | services.
73 | 5. Once you're satisfied with your setup, run "runme.py" in the main Howie
74 | directory. This launches Howie and makes him available to the world at
75 | large!
76 |
77 | ACKNOWLEDGEMENTS
78 | ----------------
79 | The Win32 installer was produced using the Nullsoft Install System
80 | (http://www.nullsoft.com/free/nsis/).
81 |
82 | The Win32 binary distribution is made possible thanks to py2exe
83 | (http://starship.python.net/crew/theller/py2exe/).
84 |
85 | Howie's conversational back-end is provided by PyAIML
86 | (http://pyaiml.sourceforge.net), a Python implementation of Dr. Richard S.
87 | Wallace's A.L.I.C.E. system. For more information about the A.L.I.C.E.
88 | Foundation (including information on AIML, the Artificial Intelligence
89 | Markup Language used to program Howie's responses), visit the A.L.I.C.E.
90 | homepage at http://www.alicebot.org/.
91 |
92 | Howie's AIM and ICQ front-ends are provided by Twisted
93 | (http://twistedmatrix.com/products/twisted).
94 |
95 | Howie's IRC front-end was written by Jamie Turner (author of Py-TOC), and is
96 | built on top of Joel Rosdahl's Python IRC library
97 | (http://python-irclib.sourceforge.net/).
98 |
99 | Howie's MSN front-end is provided by msnp, a Python MSN module by Manish
100 | Jethani (http://msnp.sourceforge.net/).
101 |
102 | Howie's Jabber front-end is provided by xmpppy (http://xmpppy.sourceforge.net).
103 |
104 | Howie is named after Howie Day (http://www.howieday.com/), for no particular
105 | reason. If it weren't for Amy Kalson, he would be named something truly boring
106 | like PyBot or PyBorg.
107 |
108 | Hooray for Python! (http://www.python.org/)
--------------------------------------------------------------------------------
/TODO.txt:
--------------------------------------------------------------------------------
1 | Additional frontends:
2 | - WEB: In progress.
3 |
4 | Additional extension modules:
5 | - Email spoofer.
6 | - Address book / contact manager
7 | - Sysadmin assistant
8 |
9 | Other features:
10 | - Auto-configuration tool (script, GUI)
11 | - Add the ability to initiate a chat session (either when a buddy logs in, or
12 | at the request of another buddy (e.g. "Hey, you should talk to SoAndSo").
13 | This will be easy in AIM, difficult in MSN (ask Mannu), and pretty much
14 | impossible in web/XMLRPC.
--------------------------------------------------------------------------------
/docs/vision.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | My Vision For Howie
5 |
6 |
7 |
8 |
My Vision For Howie
9 |
Cort Stratton (cort@users.sourceforge.net)
10 |
11 |
A Brief History Of Conversational AI
12 |
13 |
The Turing
15 | Test was proposed by legendary computer science pioneer Alan
16 | Turing as a way of measuring the intelligence of a computer
17 | program. Basically, the test challenges an artifical intelligence
18 | program to convince a human judge that it is human. The Turing
19 | Test was fiirst proposed in 1950, and despite a half-century of
20 | progress in the field of Artificial Intelligence, not a single
21 | program has ever passed it.
22 |
23 |
Nevertheless, people keep trying. Every year, a handful of the
24 | world's best conversational AI programs square off in the Loebner
26 | Prize Content (basically a formalized Turing Test, with a
27 | grand prize of US$100,000 to the first program to fool the human
28 | judges). However, after looking at the results
30 | of the 2003 Loebner Prize Contest, it's clear that
31 | conversational AI programs have a long way to go before they have
32 | any hope of passing as humans.
33 |
34 |
Several of the "best" Loebner entries are available on the Web.
35 | You can test your conversational mettle against MegaHAL, Eliza,
38 | or A.L.I.C.E. (the closest
39 | thing Howie has to a mother).
40 |
41 |
Proud To Flunk The Turing Test!
42 |
43 |
After conversing with a few chatterbots, or reading over
44 | conversational transcripts, one begins to notice a pattern:
45 | computers really aren't that interesting to talk to. Most
46 | conversations start out innocently enough, exchanging pleasantries
47 | and such. Before too long, however, the conversation devolves
48 | into one of the following scenarios:
49 |
50 |
51 |
52 |
The human begins propositioning the computer for sex. This
53 | behavior is so universally predictable that most chatterbots are
54 | actually quite comfortable with the topic. (Try this with
55 | A.L.I.C.E., incidentally).
56 |
57 |
The computer suffers a logic error, and spits out a non
58 | sequitor. Depending on how interesting/humorous the
59 | computer's response is, the human continues to feed in
60 | increasingly nonsensical input, curious to see how the program
61 | will respond.
62 |
63 |
The program suffers from severe short-term memory loss (an
64 | affliction which is sadly widespread in modern conversational
65 | AIs), and becomes unable to remember anything further back than
66 | the most recent human statement. The conversation quickly
67 | becomes a stream of content-free conversational no-ops
68 | (e.g. "Ah, I understand.", "You do?", "Yes.", "Good.", "You are
69 | pleased?", "Yes.", "Excellent.", "Thank you.", "You're
70 | welcome!", "Don't mention it.", and so on). Eventually, the
71 | human loses interest.
72 |
73 |
74 |
75 |
In short, you aren't going to see Howie entering the Loebner
76 | Prize Contest any time soon. Howie is proud to stand and be
77 | counted among the losers!
78 |
79 |
A New Frontier in Human-Computer Interaction
80 |
81 |
82 |
83 |
84 |
85 |
--------------------------------------------------------------------------------
/howie.ini:
--------------------------------------------------------------------------------
1 | # Brief description of general options:
2 | # -------------------------------------
3 | # logging: should the bot keep logs of all conversatons [yes/no]
4 | # logdir: if logging is enabled, which directory should the logs be kept in?
5 | # maxdelay: maximum artificial delay (in seconds) between responses. Used
6 | # to make the bot seem more human.
7 | # sessionspersist: Should the bot use persistent sessions? (basically, should
8 | # it remember what it learns about its visitors if the bot
9 | # is restarted? [yes/no]
10 | # sessionsdir: If persistent sessions are enabled, which directory should the
11 | # session data be saved to?
12 | # verbose: Should the bot print extra debugging information [yes/no]
13 | [general]
14 | logging = no
15 | logdir = logs
16 | maxdelay = 0
17 | sessionspersist = no
18 | sessionsdir = sessions
19 | verbose = no
20 |
21 | #
22 | # Bot Information. This is where you describe your bot.
23 | # Any entries in this section will be available through the AIML
24 | # element, where XXX is the name of the entry.
25 | # For example, will evaluate to whatever you
26 | # enter for the value of "master" below ("Your Name" by default).
27 | #
28 | # You may add as many entries as you'd like to this section. Give
29 | # your bot a favoritemovie, a hometown or a significantother!
30 | #
31 | [botinfo]
32 | name = Howie
33 | master = Your Name
34 |
35 | #
36 | # Front-end-specific options follow. Each section has an "active" option
37 | # which indicates whether that front-end should be enabled or not [yes/no].
38 | #
39 | # NOTE: All screenname/password fields can be left blank, in which case
40 | # Howie will prompt for the necessary information at startup.
41 | #
42 |
43 | # The AOL Instant Messenger interface.
44 | [aim]
45 | active = no
46 | screenname =
47 | password =
48 | profile = Bot's profile goes here.
49 |
50 | # The ICQ interface.
51 | [icq]
52 | active = no
53 | screenname =
54 | password =
55 | profile = Bot's profile goes here.
56 |
57 | # The IRC interface
58 | [irc]
59 | active = no
60 | server =
61 | port = 6667
62 | nick =
63 | channel =
64 |
65 | # The Jabber chat interface. By default, Howie attempts to connect through
66 | # port 5223 using a secure SSL connection; if your server does not support
67 | # SSL, you should change the port number below to 5222.
68 | [jabber]
69 | active = no
70 | username =
71 | password =
72 | server = jabber.org
73 | port = 5223
74 | resource = default
75 | nickname = Howie
76 |
77 | # The MSN Messenger interface
78 | [msn]
79 | active = no
80 | screenname =
81 | password =
82 | displayname = Howie
83 |
84 | # The local TTY (text console) interface.
85 | [tty]
86 | active = yes
87 |
88 | # The XML-RPC interface.
89 | # This interface serves a single function: respond(input,sessionID).
90 | # The "input" parameter contains the user's input, and the "user" parameter
91 | # contains the unique session identifier string (usually the user's name).
92 | # It returns the bot's response.
93 | [xmlrpc]
94 | active = no
95 | port = 8000
96 |
--------------------------------------------------------------------------------
/howie.nsi:
--------------------------------------------------------------------------------
1 | # howie.nsi
2 | #
3 | # Author: Cort Stratton (cortATcortstrattonDOTorg)
4 | #
5 |
6 | !include "MUI.nsh"
7 |
8 | #--------------------------------
9 | #Configuration
10 |
11 | # Basic definitions
12 | Var MY_PRODUCT
13 | Var MY_VERSION
14 | !define MY_PRODUCT "Howie"
15 | !define MY_VERSION "0.6.0"
16 |
17 | # General
18 | Name "${MY_PRODUCT}"
19 | OutFile "..\dist\howie-install-${MY_VERSION}.exe"
20 |
21 | # Folder selection page
22 | InstallDir "$PROGRAMFILES\${MY_PRODUCT}"
23 | InstallDirRegKey HKLM "Software\${MY_PRODUCT}" "Install_Dir"
24 |
25 | # MUI stuff
26 | Var MUI_TEMP
27 | Var STARTMENU_FOLDER
28 |
29 | # Compiler configuration
30 | SetCompressor bzip2
31 | ShowInstDetails show
32 | ShowUninstDetails show
33 | InstProgressFlags smooth colored
34 | XPStyle on
35 |
36 | #--------------------------------
37 | #Modern UI Configuration
38 |
39 | !insertmacro MUI_PAGE_COMPONENTS
40 | !insertmacro MUI_PAGE_DIRECTORY
41 | !define MUI_STARTMENUPAGE_REGISTRY_ROOT "HKLM"
42 | !define MUI_STARTMENUPAGE_REGISTRY_KEY "Software\${MY_PRODUCT}"
43 | !define MUI_STARTMENUPAGE_REGISTRY_VALUENAME "Start Menu Folder"
44 | !insertmacro MUI_PAGE_STARTMENU Application $STARTMENU_FOLDER
45 | !insertmacro MUI_PAGE_INSTFILES
46 | !define MUI_FINISHPAGE_RUN_NOTCHECKED
47 | !define MUI_FINISHPAGE_SHOWREADME "$INSTDIR\README.txt"
48 | !define MUI_FINISHPAGE_NOREBOOTSUPPORT
49 | !insertmacro MUI_PAGE_FINISH
50 |
51 | !define MUI_ABORTWARNING
52 |
53 | !insertmacro MUI_UNPAGE_CONFIRM
54 | !insertmacro MUI_UNPAGE_INSTFILES
55 |
56 | #--------------------------------
57 | #Languages
58 |
59 | !insertmacro MUI_LANGUAGE "English"
60 |
61 | #--------------------------------
62 | #Language Strings
63 |
64 | # Description
65 | LangString DESC_SecCopyMain ${LANG_ENGLISH} "Installs ${MY_PRODUCT} files to the application folder."
66 | LangString DESC_SecCopyAddOns ${LANG_ENGLISH} "Installs some optional add-on modules to extend ${MY_PRODUCT}'s capabilities."
67 | LangString DESC_SecCopyAcronym ${LANG_ENGLISH} "Handles 'what does X stand for' questions."
68 | LangString DESC_SecCopyGooglism ${LANG_ENGLISH} "Handles 'who/what/where/when is X' questions."
69 | LangString DESC_SecCopyRhyme ${LANG_ENGLISH} "Handles 'what rhymes with X' questions."
70 |
71 | #--------------------------------
72 | #Reserve Files
73 |
74 | # Things that need to be extracted on first (keep these lines before any
75 | # File command!). Only useful for BZIP2 compression.
76 | !insertmacro MUI_RESERVEFILE_LANGDLL
77 |
78 | #--------------------------------
79 | #Installer Sections
80 |
81 | Section "!${MY_PRODUCT} (required)" SecCopyMain
82 | # Indicate that this section should always be installed.
83 | SectionIn RO
84 |
85 | # Set output path to the installation directory.
86 | SetOutPath $INSTDIR
87 |
88 | # Install core files.
89 | DetailPrint "Installing core files..."
90 | SetDetailsPrint textonly
91 | File /r dist\*
92 | Rename runme.exe howie.exe
93 | SetDetailsPrint both
94 |
95 | # Install documentation
96 | DetailPrint "Installing documentation..."
97 | SetDetailsPrint textonly
98 | SetOutPath $INSTDIR\docs
99 | File /r docs\*.html
100 | SetDetailsPrint both
101 |
102 | # Install uninstaller program
103 | DetailPrint "Installing uninstaller..."
104 | SetDetailsPrint textonly
105 | SetOutPath $INSTDIR
106 | WriteUninstaller Uninstall.exe
107 | WriteRegStr HKLM \
108 | "Software\Microsoft\Windows\CurrentVersion\Uninstall\${MY_PRODUCT}" \
109 | "DisplayName" "Howie ${MY_VERSION} (remove only)"
110 | WriteRegStr HKLM \
111 | "Software\Microsoft\Windows\CurrentVersion\Uninstall\${MY_PRODUCT}" \
112 | "UninstallString" "$INSTDIR\Uninstall.exe"
113 | WriteRegDWORD HKLM \
114 | "Software\Microsoft\Windows\CurrentVersion\Uninstall\${MY_PRODUCT}" \
115 | "NoModify" 1
116 | WriteRegDWORD HKLM \
117 | "Software\Microsoft\Windows\CurrentVersion\Uninstall\${MY_PRODUCT}" \
118 | "NoRepair" 1
119 | WriteRegStr HKLM "Software\${MY_PRODUCT}" "Installer Language" $LANGUAGE
120 | SetDetailsPrint both
121 |
122 | # Write Start Menu shortcuts
123 | !insertmacro MUI_STARTMENU_WRITE_BEGIN Application
124 | # Create shortcuts
125 | DetailPrint "Installing Start Menu shortcuts..."
126 | SetDetailsPrint textonly
127 | CreateDirectory "$SMPROGRAMS\$STARTMENU_FOLDER"
128 | SetOutPath $INSTDIR # To set working directory for shortcut
129 | CreateShortCut "$SMPROGRAMS\$STARTMENU_FOLDER\Configure ${MY_PRODUCT}.lnk" \
130 | "$INSTDIR\howie.ini"
131 | CreateShortCut "$SMPROGRAMS\$STARTMENU_FOLDER\Run ${MY_PRODUCT}.lnk" \
132 | "$INSTDIR\howie.exe"
133 | CreateShortCut "$SMPROGRAMS\$STARTMENU_FOLDER\Run ${MY_PRODUCT} (Local Mode).lnk" \
134 | "$INSTDIR\howie.exe" "-l"
135 | CreateShortCut "$SMPROGRAMS\$STARTMENU_FOLDER\Uninstall ${MY_PRODUCT}.lnk" \
136 | "$INSTDIR\Uninstall.exe"
137 | CreateShortCut "$SMPROGRAMS\$STARTMENU_FOLDER\README.lnk" \
138 | "$INSTDIR\README.txt"
139 |
140 | # Write shortcut location to the registry (for Uninstaller)
141 | WriteRegStr HKLM "Software\${MY_PRODUCT}" "Start Menu Folder" "$STARTMENU_FOLDER"
142 | SetDetailsPrint both
143 | !insertmacro MUI_STARTMENU_WRITE_END
144 | SectionEnd
145 |
146 | SubSection "Add-ons" SecCopyAddOns
147 | Section "Acronyms" SecCopyAcronym
148 | # Install acronym
149 | DetailPrint "Installing Acronym module..."
150 | SetDetailsPrint textonly
151 | SetOutPath $INSTDIR\scripts
152 | File scripts\acronym.py
153 | SetOutPath $INSTDIR\standard
154 | File standard\howie-acronym.aiml
155 | SetDetailsPrint both
156 | SectionEnd
157 |
158 | Section "Googlisms" SecCopyGooglism
159 | # Install googlism
160 | DetailPrint "Installing Googlism module..."
161 | SetDetailsPrint textonly
162 | SetOutPath $INSTDIR\scripts
163 | File scripts\googlism.py
164 | SetOutPath $INSTDIR\standard
165 | File standard\howie-googlism.aiml
166 | SetDetailsPrint both
167 | SectionEnd
168 |
169 | # Install rhyme
170 | Section "Rhymes" SecCopyRhyme
171 | DetailPrint "Installing Rhymes module..."
172 | SetDetailsPrint textonly
173 | SetOutPath $INSTDIR\scripts
174 | File scripts\rhyme.py
175 | File scripts\*.db
176 | SetOutPath $INSTDIR\standard
177 | File standard\howie-rhyme.aiml
178 | SetDetailsPrint both
179 | SectionEnd
180 | SubSectionEnd
181 |
182 | #--------------------------------
183 | #Installer Functions
184 |
185 | Function .onInit
186 | # Splash screen
187 | #SetOutPath $TEMP
188 | #File /oname=spltmp.bmp "logo.bmp"
189 | #advsplash::show 2000 500 500 -1 $TEMP\spltmp
190 |
191 | # $0 has '1' if the user closed the splash screen early,
192 | # '0' if everything closed normal, and '-1' if some error occured.
193 | #Pop $0
194 | #Delete $TEMP\spltmp.bmp
195 |
196 |
197 | # Language selection
198 |
199 | # Font
200 | Push Tahoma
201 | Push 8
202 |
203 | # Languages
204 | !insertmacro MUI_LANGDLL_DISPLAY
205 | FunctionEnd
206 |
207 | #--------------------------------
208 | #Descriptions
209 |
210 | !insertmacro MUI_FUNCTION_DESCRIPTION_BEGIN
211 | !insertmacro MUI_DESCRIPTION_TEXT ${SecCopyMain} $(DESC_SecCopyMain)
212 | !insertmacro MUI_DESCRIPTION_TEXT ${SecCopyAddOns} $(DESC_SecCopyAddOns)
213 | !insertmacro MUI_DESCRIPTION_TEXT ${SecCopyAcronym} $(DESC_SecCopyAcronym)
214 | !insertmacro MUI_DESCRIPTION_TEXT ${SecCopyGooglism} $(DESC_SecCopyGooglism)
215 | !insertmacro MUI_DESCRIPTION_TEXT ${SecCopyRhyme} $(DESC_SecCopyRhyme)
216 | !insertmacro MUI_FUNCTION_DESCRIPTION_END
217 |
218 | #--------------------------------
219 | #Uninstaller Section
220 |
221 | Section "Uninstall"
222 | RMDir /r "$INSTDIR"
223 | !insertmacro MUI_STARTMENU_GETFOLDER Application $MUI_TEMP
224 |
225 | Delete "$SMPROGRAMS\$MUI_TEMP\Configure ${MY_PRODUCT}.lnk"
226 | Delete "$SMPROGRAMS\$MUI_TEMP\Uninstall ${MY_PRODUCT}.lnk"
227 | Delete "$SMPROGRAMS\$MUI_TEMP\Run ${MY_PRODUCT}.lnk"
228 | Delete "$SMPROGRAMS\$MUI_TEMP\Run ${MY_PRODUCT} (Local Mode).lnk"
229 | Delete "$SMPROGRAMS\$MUI_TEMP\README.lnk"
230 |
231 | ;Delete empty start menu parent diretories
232 | StrCpy $MUI_TEMP "$SMPROGRAMS\$MUI_TEMP"
233 |
234 | startMenuDeleteLoop:
235 | RMDir $MUI_TEMP
236 | GetFullPathName $MUI_TEMP "$MUI_TEMP\.."
237 |
238 | IfErrors startMenuDeleteLoopDone
239 |
240 | StrCmp $MUI_TEMP $SMPROGRAMS startMenuDeleteLoopDone startMenuDeleteLoop
241 | startMenuDeleteLoopDone:
242 |
243 | DeleteRegKey /ifempty HKLM "Software\${MY_PRODUCT}"
244 | SectionEnd
245 |
246 | #--------------------------------
247 | #Uninstaller Functions
248 |
249 | Function un.onInit
250 | # Get language from registry
251 | ReadRegStr $LANGUAGE HKLM "Software\${MY_PRODUCT}" "Installer Language"
252 | FunctionEnd
253 |
--------------------------------------------------------------------------------
/howie/__init__.py:
--------------------------------------------------------------------------------
1 | __all__ = ["configFile", "core"]
2 |
--------------------------------------------------------------------------------
/howie/aiml/DefaultSubs.py:
--------------------------------------------------------------------------------
1 | """This file contains the default (English) substitutions for the
2 | PyAIML kernel. These substitutions may be overridden by using the
3 | Kernel.loadSubs(filename) method. The filename specified should refer
4 | to a Windows-style INI file with the following format:
5 |
6 | # lines that start with '#' are comments
7 |
8 | # The 'gender' section contains the substitutions performed by the
9 | # AIML tag, which swaps masculine and feminine pronouns.
10 | [gender]
11 | he = she
12 | she = he
13 | # and so on...
14 |
15 | # The 'person' section contains the substitutions performed by the
16 | # AIML tag, which swaps 1st and 2nd person pronouns.
17 | [person]
18 | I = you
19 | you = I
20 | # and so on...
21 |
22 | # The 'person2' section contains the substitutions performed by
23 | # the AIML tag, which swaps 1st and 3nd person pronouns.
24 | [person2]
25 | I = he
26 | he = I
27 | # and so on...
28 |
29 | # the 'normal' section contains subtitutions run on every input
30 | # string passed into Kernel.respond(). It's mainly used to
31 | # correct common misspellings, and to convert contractions
32 | # ("WHAT'S") into a format that will match an AIML pattern ("WHAT
33 | # IS").
34 | [normal]
35 | what's = what is
36 | """
37 |
38 | defaultGender = {
39 | # masculine -> feminine
40 | "he": "she",
41 | "him": "her",
42 | "his": "her",
43 | "himself": "herself",
44 |
45 | # feminine -> masculine
46 | "she": "he",
47 | "her": "him",
48 | "hers": "his",
49 | "herself": "himself",
50 | }
51 |
52 | defaultPerson = {
53 | # 1st->3rd (masculine)
54 | "I": "he",
55 | "me": "him",
56 | "my": "his",
57 | "mine": "his",
58 | "myself": "himself",
59 |
60 | # 3rd->1st (masculine)
61 | "he":"I",
62 | "him":"me",
63 | "his":"my",
64 | "himself":"myself",
65 |
66 | # 3rd->1st (feminine)
67 | "she":"I",
68 | "her":"me",
69 | "hers":"mine",
70 | "herself":"myself",
71 | }
72 |
73 | defaultPerson2 = {
74 | # 1st -> 2nd
75 | "I": "you",
76 | "me": "you",
77 | "my": "your",
78 | "mine": "yours",
79 | "myself": "yourself",
80 |
81 | # 2nd -> 1st
82 | "you": "me",
83 | "your": "my",
84 | "yours": "mine",
85 | "yourself": "myself",
86 | }
87 |
88 |
89 | # TODO: this list is far from complete
90 | defaultNormal = {
91 | "wanna": "want to",
92 | "gonna": "going to",
93 |
94 | "I'm": "I am",
95 | "I'd": "I would",
96 | "I'll": "I will",
97 | "I've": "I have",
98 | "you'd": "you would",
99 | "you're": "you are",
100 | "you've": "you have",
101 | "you'll": "you will",
102 | "he's": "he is",
103 | "he'd": "he would",
104 | "he'll": "he will",
105 | "she's": "she is",
106 | "she'd": "she would",
107 | "she'll": "she will",
108 | "we're": "we are",
109 | "we'd": "we would",
110 | "we'll": "we will",
111 | "we've": "we have",
112 | "they're": "they are",
113 | "they'd": "they would",
114 | "they'll": "they will",
115 | "they've": "they have",
116 |
117 | "y'all": "you all",
118 |
119 | "can't": "can not",
120 | "cannot": "can not",
121 | "couldn't": "could not",
122 | "wouldn't": "would not",
123 | "shouldn't": "should not",
124 |
125 | "isn't": "is not",
126 | "ain't": "is not",
127 | "don't": "do not",
128 | "aren't": "are not",
129 | "won't": "will not",
130 | "weren't": "were not",
131 | "wasn't": "was not",
132 | "didn't": "did not",
133 | "hasn't": "has not",
134 | "hadn't": "had not",
135 | "haven't": "have not",
136 |
137 | "where's": "where is",
138 | "where'd": "where did",
139 | "where'll": "where will",
140 | "who's": "who is",
141 | "who'd": "who did",
142 | "who'll": "who will",
143 | "what's": "what is",
144 | "what'd": "what did",
145 | "what'll": "what will",
146 | "when's": "when is",
147 | "when'd": "when did",
148 | "when'll": "when will",
149 | "why's": "why is",
150 | "why'd": "why did",
151 | "why'll": "why will",
152 |
153 | "it's": "it is",
154 | "it'd": "it would",
155 | "it'll": "it will",
156 | }
--------------------------------------------------------------------------------
/howie/aiml/Kernel.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/linzhp/Howie/c7aa0eb5ea55065870d10fdbc95baff243fac1dc/howie/aiml/Kernel.py
--------------------------------------------------------------------------------
/howie/aiml/Utils.py:
--------------------------------------------------------------------------------
1 | """This file contains assorted general utility functions used by other
2 | modules in the PyAIML package.
3 |
4 | """
5 |
6 | def sentences(s):
7 | """Split the string s into a list of sentences."""
8 | try: s+""
9 | except: raise TypeError, "s must be a string"
10 | pos = 0
11 | sentenceList = []
12 | l = len(s)
13 | while pos < l:
14 | try: p = s.index('.', pos)
15 | except: p = l+1
16 | try: q = s.index('?', pos)
17 | except: q = l+1
18 | try: e = s.index('!', pos)
19 | except: e = l+1
20 | end = min(p,q,e)
21 | sentenceList.append( s[pos:end].strip() )
22 | pos = end+1
23 | # If no sentences were found, return a one-item list containing
24 | # the entire input string.
25 | if len(sentenceList) == 0: sentenceList.append(s)
26 | return sentenceList
27 |
28 | # Self test
29 | if __name__ == "__main__":
30 | # sentences
31 | sents = sentences("First. Second, still? Third and Final! Well, not really")
32 | assert(len(sents) == 4)
--------------------------------------------------------------------------------
/howie/aiml/WordSub.py:
--------------------------------------------------------------------------------
1 | """This module implements the WordSub class, modelled after a recipe
2 | in "Python Cookbook" (Recipe 3.14, "Replacing Multiple Patterns in a
3 | Single Pass" by Xavier Defrang).
4 |
5 | Usage:
6 | Use this class like a dictionary to add before/after pairs:
7 | > subber = TextSub()
8 | > subber["before"] = "after"
9 | > subber["begin"] = "end"
10 | Use the sub() method to perform the substitution:
11 | > print subber.sub("before we begin")
12 | after we end
13 | All matching is intelligently case-insensitive:
14 | > print subber.sub("Before we BEGIN")
15 | After we END
16 | The 'before' words must be complete words -- no prefixes.
17 | The following example illustrates this point:
18 | > subber["he"] = "she"
19 | > print subber.sub("he says he'd like to help her")
20 | she says she'd like to help her
21 | Note that "he" and "he'd" were replaced, but "help" and "her" were
22 | not.
23 | """
24 |
25 | # 'dict' objects weren't available to subclass from until version 2.2.
26 | # Get around this by importing UserDict.UserDict if the built-in dict
27 | # object isn't available.
28 | try: dict
29 | except: from UserDict import UserDict as dict
30 |
31 | import ConfigParser
32 | import re
33 | import string
34 |
35 | class WordSub(dict):
36 | """All-in-one multiple-string-substitution class."""
37 |
38 | def _wordToRegex(self, word):
39 | """Convert a word to a regex object which matches the word."""
40 | return r"\b%s\b" % re.escape(word)
41 |
42 | def _update_regex(self):
43 | """Build re object based on the keys of the current
44 | dictionary.
45 |
46 | """
47 | self._regex = re.compile("|".join(map(self._wordToRegex, self.keys())))
48 | self._regexIsDirty = False
49 |
50 | def __init__(self, defaults = {}):
51 | """Initialize the object, and populate it with the entries in
52 | the defaults dictionary.
53 |
54 | """
55 | self._regex = None
56 | self._regexIsDirty = True
57 | for k,v in defaults.items():
58 | self[k] = v
59 |
60 | def __call__(self, match):
61 | """Handler invoked for each regex match."""
62 | return self[match.group(0)]
63 |
64 | def __setitem__(self, i, y):
65 | self._regexIsDirty = True
66 | # for each entry the user adds, we actually add three entrys:
67 | super(type(self),self).__setitem__(string.lower(i),string.lower(y)) # key = value
68 | super(type(self),self).__setitem__(string.capwords(i), string.capwords(y)) # Key = Value
69 | super(type(self),self).__setitem__(string.upper(i), string.upper(y)) # KEY = VALUE
70 |
71 | def sub(self, text):
72 | """Translate text, returns the modified text."""
73 | if self._regexIsDirty:
74 | self._update_regex()
75 | return self._regex.sub(self, text)
76 |
77 | # self-test
78 | if __name__ == "__main__":
79 | subber = WordSub()
80 | subber["apple"] = "banana"
81 | subber["orange"] = "pear"
82 | subber["banana" ] = "apple"
83 | subber["he"] = "she"
84 | subber["I'd"] = "I would"
85 |
86 | # test case insensitivity
87 | inStr = "I'd like one apple, one Orange and one BANANA."
88 | outStr = "I Would like one banana, one Pear and one APPLE."
89 | if subber.sub(inStr) == outStr: print "Test #1 PASSED"
90 | else: print "Test #1 FAILED: '%s'" % subber.sub(inStr)
91 |
92 | inStr = "He said he'd like to go with me"
93 | outStr = "She said she'd like to go with me"
94 | if subber.sub(inStr) == outStr: print "Test #2 PASSED"
95 | else: print "Test #2 FAILED: '%s'" % subber.sub(inStr)
--------------------------------------------------------------------------------
/howie/aiml/__init__.py:
--------------------------------------------------------------------------------
1 | __all__ = []
2 |
3 | # The Kernel class is the only class most implementations should need.
4 | from Kernel import Kernel
5 |
--------------------------------------------------------------------------------
/howie/aiml/self-test.aiml:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/linzhp/Howie/c7aa0eb5ea55065870d10fdbc95baff243fac1dc/howie/aiml/self-test.aiml
--------------------------------------------------------------------------------
/howie/configFile.py:
--------------------------------------------------------------------------------
1 | """
2 | Handles the reading, writing of (and general access to) Howie's
3 | persistent configuration information, stored (by default) in
4 | the howie.ini file.
5 | """
6 |
7 | import os
8 | import string
9 | import sys
10 |
11 | import ConfigParser
12 | from howie import frontends
13 | from frontends import *
14 |
15 | configFileName = "howie.ini"
16 |
17 | # Load default values for various config-file options.
18 | # The defaults are scattered throughout the frontend and
19 | # backend modules, each of which may have a dictionary
20 | # attribute called configDefaults similar to the one
21 | # below. This code merges all the configDefaults into
22 | # one master copy.
23 | configDefaults = {
24 | "general.logging": "no",
25 | "general.logdir": "logs",
26 | "general.maxdelay": "0",
27 | "general.sessionspersist": "no",
28 | "general.sessionsdir": "sessions",
29 | "general.verbose": "no",
30 | }
31 | for package in ['frontends']:
32 | for name in eval("%s.__all__" % package):
33 | mod = eval("%s.%s" % (package, name))
34 | try: defaults = mod.configDefaults
35 | except AttributeError: continue
36 | for k,v in mod.configDefaults.items():
37 | if configDefaults.has_key(k):
38 | continue
39 | configDefaults[k] = v
40 |
41 |
42 | def _WriteINI(file, config=configDefaults):
43 | """
44 | Writes the config dictionary to a .INI file.
45 | """
46 | if len(config) == 0:
47 | return
48 | iniFile = open(file, "w")
49 | currentSection = ""
50 | keys = config.keys()
51 | keys.sort()
52 | for key in keys:
53 | # Don't write entries with no value
54 | value = config[key]
55 | if value == "":
56 | continue
57 |
58 | # Split the key into section and variable.
59 | section, var = string.split(key, ".", 1)
60 | if section != currentSection:
61 | # start a new section
62 | if currentSection:
63 | iniFile.write("\n")
64 | iniFile.write("[%s]\n" % section)
65 | currentSection = section
66 |
67 | # write the entry
68 | iniFile.write("%s = %s\n" % (var, value))
69 | iniFile.close()
70 |
71 | def _ReadINI(file, config={}):
72 | """
73 | Returns a dictionary with keys of the form
74 | .