guppy 7.59 KB
Newer Older
1
#!/usr/bin/env python3
Svetlana Tkachenko's avatar
gplv3    
Svetlana Tkachenko committed
2
#    guppy Copyright (C) 2010-2011 guppy team members.
Svetlana Tkachenko's avatar
Svetlana Tkachenko committed
3
#
Svetlana Tkachenko's avatar
gplv3    
Svetlana Tkachenko committed
4
5
6
#    This program 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.
7
8
9
10
#  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.
11
#
12
13
14
15
#  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.
16
#
17
18
19
20
#  You should have received a copy of the GNU General Public License
#  along with this program; if not, write to the Free Software
#  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
#  MA 02110-1301, USA.
Svetlana Tkachenko's avatar
Svetlana Tkachenko committed
21

Svetlana Tkachenko's avatar
Svetlana Tkachenko committed
22
import sys
Svetlana Tkachenko's avatar
Svetlana Tkachenko committed
23
24
25
26
27
28

if sys.version_info[0] < 3:
    print("Error: guppy only works with Python 3+. Please install python 3 and re-try.")
    exit()


Svetlana Tkachenko's avatar
Svetlana Tkachenko committed
29
import os
Svetlana Tkachenko's avatar
Svetlana Tkachenko committed
30
import configparser
Svetlana Tkachenko's avatar
Svetlana Tkachenko committed
31
32
import asyncore
import irc
33
import time
Svetlana Tkachenko's avatar
Svetlana Tkachenko committed
34

35

Svetlana Tkachenko's avatar
Svetlana Tkachenko committed
36
37
38
class main(object):
    def __init__(self):
        # Constant.
39
        self.version = "0.4.4"
40
        self.homedir = os.path.abspath(os.path.dirname(__file__))
Svetlana Tkachenko's avatar
Svetlana Tkachenko committed
41
42
        print("  __ _ _   _ _ __  _ __  _   _ ")
        print(" / _` | | | | '_ \| '_ \| | | | http://repo.or.cz/w/guppy.git/summary")
Svetlana Tkachenko's avatar
gplv3    
Svetlana Tkachenko committed
43
        print("| (_| | |_| | |_) | |_) | |_| | irc://irc.freenode.net/guppy")
Svetlana Tkachenko's avatar
Svetlana Tkachenko committed
44
        print(" \__, |\__,_| .__/| .__/ \__, | ")
45
46
        print(" |___/      |_|   |_|    |___/  version " + self.version)
        print("PID: " + str(os.getpid()))
47
        self.directory = self.homedir + '/conf/'
48
        print("Settings directory: " + self.directory)
Svetlana Tkachenko's avatar
Svetlana Tkachenko committed
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65

        if not os.path.exists(self.directory):
            os.makedirs(self.directory)
        self.configpath = self.directory + 'main.cfg'
        self.logpath = self.directory + 'main.log'

        helptext = """
usage: guppy.py [-h] [-c] [-v]

Start guppy - a modular Python IRC bot.

optional arguments:
  -h, --help      show this help message and exit
  -c, --makeconf  generate a new configuration file
  -v, --version   display version information and exit.
"""
        if "-h" in sys.argv[1:] or "--help" in sys.argv[1:]:
Svetlana Tkachenko's avatar
Svetlana Tkachenko committed
66
            print(helptext)
Svetlana Tkachenko's avatar
Svetlana Tkachenko committed
67
            exit()
68

Svetlana Tkachenko's avatar
Svetlana Tkachenko committed
69
70
        if "-v" in sys.argv[1:] or "--version" in sys.argv[1:]:
            exit()
71

Svetlana Tkachenko's avatar
Svetlana Tkachenko committed
72
73
74
        if "-c" in sys.argv[1:] or "--makeconf" in sys.argv[1:]:
            self.makeconf()

75
        if not os.path.isfile(self.configpath):
Svetlana Tkachenko's avatar
Svetlana Tkachenko committed
76
77
78
            print("No configuration file found, running makeconf")
            self.makeconf()

Svetlana Tkachenko's avatar
Svetlana Tkachenko committed
79
        self.config = configparser.RawConfigParser()
Svetlana Tkachenko's avatar
Svetlana Tkachenko committed
80
        self.config.read(self.configpath)
81

Svetlana Tkachenko's avatar
Svetlana Tkachenko committed
82
83
84
    def start(self):
        self.clients = []
        for section in self.config.sections():
85
            server_config = {"network": section, "version": self.version, "confdir": self.directory}
86
            for item, value in self.config.items(section):
Svetlana Tkachenko's avatar
Svetlana Tkachenko committed
87
                server_config[item] = value
88

89
            print("%s [%s] Connecting..." % (time.strftime("%Y-%m-%d %H:%M:%S"), server_config["network"]))
Svetlana Tkachenko's avatar
Svetlana Tkachenko committed
90
            self.clients.append(irc.IRC(server_config))
91
        while 1:
Svetlana Tkachenko's avatar
Svetlana Tkachenko committed
92
93
94
95
            try:
                asyncore.loop()
            except:
                time.sleep(5)
96

Svetlana Tkachenko's avatar
Svetlana Tkachenko committed
97
98
99
100
    def stop(self):
        for client in self.clients:
            client.doQuit("Keyboard interrupt.")
            client.pluginManager.unloadAllPlugins()
101

102
    def my_raw(self, prompt="", default=""):
auscompgeek's avatar
auscompgeek committed
103
        ret = eval("'" + input("%s [%s]: " % (prompt, default)) + "'")
Svetlana Tkachenko's avatar
Svetlana Tkachenko committed
104
        return default if ret == "" else ret
105

106
    def set(self, section, option, text, default=""):
Svetlana Tkachenko's avatar
Svetlana Tkachenko committed
107
108
        try:
            if default == "":
109
                default = self.config.get(section, option)
Svetlana Tkachenko's avatar
Svetlana Tkachenko committed
110
        except configparser.NoOptionError:
Svetlana Tkachenko's avatar
Svetlana Tkachenko committed
111
            pass
112

113
114
        value = self.my_raw(text, default)
        self.config.set(section, option, value)
115

Svetlana Tkachenko's avatar
Svetlana Tkachenko committed
116
    def makeconf(self):
Svetlana Tkachenko's avatar
Svetlana Tkachenko committed
117
        self.config = configparser.RawConfigParser()
Svetlana Tkachenko's avatar
Svetlana Tkachenko committed
118
119
        getting_servers = True
        while getting_servers:
120
            currentNetwork = self.my_raw("What IRC network do I connect to (just the name)?")
Svetlana Tkachenko's avatar
Svetlana Tkachenko committed
121
122
            try:
                self.config.add_section(currentNetwork)
Svetlana Tkachenko's avatar
Svetlana Tkachenko committed
123
            except configparser.DuplicateSectionError:
Svetlana Tkachenko's avatar
Svetlana Tkachenko committed
124
125
                overwrite = self.my_raw("Server already exists! Overwrite? (yes/no)", "no").lower()
                while overwrite != "yes" and overwrite != "y" and overwrite != "no" and overwrite != "n":
126
                    overwrite = self.my_raw("Invalid option. Overwrite configuration for " + currentNetwork + "? (yes/no)", "no").lower()
127

Svetlana Tkachenko's avatar
Svetlana Tkachenko committed
128
                if overwrite.lower() == "no" or overwrite.lower() == "n":
129
                    continue  # go back to top of "while getting_servers:"
Svetlana Tkachenko's avatar
Svetlana Tkachenko committed
130
                #else continue out of try/except
131

132
            self.set(currentNetwork, 'host', "What is the IRC network address (eg. irc.example.org)?")
133
            self.set(currentNetwork, 'channels', "What channels to automatically join (comma-separated, no spaces)?")
134
135
136
137
138
139
140
141
142
143
            self.set(currentNetwork, 'nickname', "What nickname should I use?")
            self.set(currentNetwork, 'ident', "What username (ident) should I use?")
            self.set(currentNetwork, 'owner_nick', "What is YOUR nick (used to auth, you can set password later)?")
            self.set(currentNetwork, 'ns_name', "What is my nickServ username (if there is none, press ENTER)?")
            self.set(currentNetwork, 'ns_pwd', "What is my NickServ password (if there is none, press ENTER)?")
            self.set(currentNetwork, 'srpass', "What server password should I use (used on private servers or for Services auth)?")
            self.set(currentNetwork, 'port', "What port should I use?", "6667")
            self.set(currentNetwork, 'use_ssl', 'Should I use ssl (yes/no)?', 'no')
            self.set(currentNetwork, 'ipv6', 'Should I use IPv6 to connect (yes/no)?', 'no')
            self.set(currentNetwork, "comchar", "What command char (other than my nick) should I respond to?", "-")
144
            self.set(currentNetwork, "infochar", "What command char should I use for the info plugin?", "~")       ###N# Asks for and writes the infochar to the main.cfg
145
            list1 = os.listdir(self.homedir + "/plugins")
146
            list2 = [item.replace(".py", "") for item in list1 if not '__' in item]
147
            print("Available plugins are: " + " ".join(list2))
148
            self.set(currentNetwork, "plugins", "What plugins will I load on startup (comma-separated, no spaces)?", "auth,printer,pluginloader,ping_server")
149

150
            another_server = self.my_raw("All done with " + currentNetwork + ". Add another server? (yes/no)", "no").lower()
Svetlana Tkachenko's avatar
Svetlana Tkachenko committed
151
152
            while another_server != "yes" and another_server != "y" and another_server != "no" and another_server != "n":
                another_server = self.my_raw("Invalid option. Do you want to add another server? (yes/no)", "no").lower()
153

Svetlana Tkachenko's avatar
Svetlana Tkachenko committed
154
155
156
            if another_server == "no" or another_server == "n":
                break
            #else no action needed
157

Svetlana Tkachenko's avatar
Svetlana Tkachenko committed
158
159
160
        self.writeconfig()
        print('Configuration file has been created.')
        exit()
161

Svetlana Tkachenko's avatar
Svetlana Tkachenko committed
162
163
164
165
166
167
168
169
170
    def writeconfig(self):
        configfile = open(self.configpath, 'w')
        self.config.write(configfile)
        configfile.close()

if __name__ == "__main__":
    c = None
    try:
        c = main()
171
        while True:
Svetlana Tkachenko's avatar
Svetlana Tkachenko committed
172
173
174
175
            try:
                c.start()
            except:
                time.sleep(5)
Svetlana Tkachenko's avatar
Svetlana Tkachenko committed
176
177
178
179
    except KeyboardInterrupt:
        print("Shutting down all connections...")
        c.stop()
        print("Quitting!")
180