diff --git a/bot.py b/bot.py
index 8712d91..aa9bd35 100644
--- a/bot.py
+++ b/bot.py
@@ -31,7 +31,6 @@ import os
import utils
from constants import *
-#from googleclient import GoogleClient
from Yowsup.Contacts.contacts import WAContactsSyncRequest
@@ -40,10 +39,7 @@ class Bot():
self.session = session
self.name = name
- # self.google = GoogleClient()
-
self.commands = {
-# "import": self._import,
"help": self._help,
"prune": self._prune,
"welcome": self._welcome,
@@ -79,41 +75,6 @@ class Bot():
def send(self, message):
self.session.backend.handleMessage(self.session.user, self.name, message)
-# def __do_import(self, token):
-# # Google
-# google = self.google.getContacts(token)
-# self.send("%d buddies imported from google" % len(google))
-#
-# result = { }
-# for number, name in google.iteritems():
-# number = re.sub("[^0-9]", "", number)
-# number = number if number[0] == "0" else "+" + number
-#
-# result[number] = { 'nick': name, 'state': 0 }
-#
-# # WhatsApp
-# user = self.session.legacyName
-# password = self.session.password
-# sync = WAContactsSyncRequest(user, password, result.keys())
-# whatsapp = sync.send()['c']
-#
-# for w in whatsapp:
-# result[w['p']]['state'] = w['w']
-# result[w['p']]['number'] = w['n']
-#
-# self.send("%d buddies are using whatsapp" % len(filter(lambda w: w['w'], whatsapp)))
-#
-# for r in result.values():
-# if r['nick']:
-# self.session.buddies.add(
-# number = r['number'],
-# nick = r['nick'],
-# groups = [u'Google'],
-# state = r['state']
-# )
-#
-# self.send("%d buddies imported" % len(whatsapp))
-
def __get_token(self, filename, timeout = 30):
file = open(filename, 'r')
file.seek(-1, 2) # look at the end
@@ -135,25 +96,6 @@ class Bot():
file.close()
# commands
-# def _import(self, token = None):
-# if not token:
-# token_url = self.google.getTokenUrl("http://whatsapp.0l.de/auth.py")
-# auth_url = "http://whatsapp.0l.de/auth.py?number=%s&auth_url=%s" % (self.session.legacyName, urllib.quote(token_url))
-# short_url = utils.shorten(auth_url)
-# self.send("please visit this url to auth: %s" % short_url)
-#
-# self.send("waiting for authorization...")
-# token = self.__get_token(TOKEN_FILE)
-# if token:
-# self.send("got token: %s" % token)
-# self.__do_import(token)
-# self.session.updateRoster()
-# else:
-# self.send("timeout! please use \"\\import [token]\"")
-# else:
-# self.__do_import(token)
-# self.session.updateRoster()
-
def _sync(self):
user = self.session.legacyName
password = self.session.password
@@ -170,7 +112,6 @@ class Bot():
self.send("""following bot commands are available:
\\help show this message
\\prune clear your buddylist
-\\import [token] import buddies from Google
\\sync sync your imported contacts with WhatsApp
\\fortune [database] give me a quote
diff --git a/cgi/auth.py b/cgi/auth.py
deleted file mode 100755
index 5eeb3c0..0000000
--- a/cgi/auth.py
+++ /dev/null
@@ -1,73 +0,0 @@
-#!/usr/bin/python
-
-__author__ = "Steffen Vogel"
-__copyright__ = "Copyright 2013, Steffen Vogel"
-__license__ = "GPLv3"
-__maintainer__ = "Steffen Vogel"
-__email__ = "post@steffenvogel.de"
-__status__ = "Prototype"
-
-"""
- This file is part of transWhat
-
- transWhat 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 3 of the License, or
- any later version.
-
- transwhat 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 transWhat. If not, see .
-"""
-
-import os
-import sys
-import cgi
-import cgitb
-import time
-
-sys.path.insert(1, os.path.join(sys.path[0], '..'))
-
-from constants import *
-
-def cookies(str):
- return dict(c.split('=') for c in str.split(";"))
-
-def save_token(timestamp, number, token, filename="tokens"):
- file = open(filename, 'a')
- file.write("%s\t%s\t%s\n" % (str(timestamp), number, token))
- file.close()
-
-def main():
- form = cgi.FieldStorage()
- number = form.getfirst("number")
- auth_url = form.getfirst("auth_url")
- token = form.getfirst("code")
-
- if auth_url:
- print "Status: 301 Moved"
- print "Location: %s" % auth_url
- print "Content-type: text/html"
- print "Set-Cookie: number=%s" % number
- print "\n\n";
-
- elif token and os.environ.has_key('HTTP_COOKIE'):
- print "Status: 301 Moved"
- print "Content-type: text/html"
- print "Location: http://whatsapp.0l.de"
- print
-
- c = cookies(os.environ['HTTP_COOKIE'])
- save_token(time.time(), c['number'], token, TOKEN_FILE)
-
- else:
- print "Content-type: text/html"
- print "\n"
- print "something strange happened :("
-
-if __name__ == "__main__":
- main()
diff --git a/cgi/index.html b/cgi/index.html
deleted file mode 100644
index 99a9632..0000000
--- a/cgi/index.html
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
-
-
-
-
-
-
-
-
diff --git a/cgi/sipgate.py b/cgi/sipgate.py
deleted file mode 100644
index a3ece4b..0000000
--- a/cgi/sipgate.py
+++ /dev/null
@@ -1,237 +0,0 @@
-#!/usr/bin/env python
-# -*- encoding: UTF8 -*-
-
-# author: Philipp Klaus, philipp.klaus →AT→ gmail.com
-
-# This file is part of python-sipgate-xmlrpc.
-#
-# python-sipgate-xmlrpc 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 3 of the License, or
-# (at your option) any later version.
-#
-# python-sipgate-xmlrpc 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 python-sipgate-xmlrpc. If not, see .
-
-
-#####################################################################
-###### This the most important file of the project: #######
-###### It contains the classe api, which #######
-###### implements the XML-RPC communication with the #######
-###### Sipgate API. #######
-
-#from time import time
-from sys import stderr
-from xmlrpclib import ServerProxy, Fault, ProtocolError, ResponseError
-from exceptions import TypeError
-from socket import error as socket_error
-import re
-
-VERSION = "0.9.2"
-NAME = "%s - python-sipgate-xmlrpc/sipgate.py"
-VENDOR = "https://github.com/pklaus/python-sipgate-xmlrpc"
-
-### ------- Here comes the most important piece of code: the api class with magic methods -----
-
-class api (ServerProxy):
- def __init__ (self, username=False, password=False, prog_name=False, verbose=False):
- if not (username and password and prog_name):
- raise SipgateAPIException('To use the class sipgate.api you must provide, username, password and a program name.')
- address = SIPGATE_API_URL % {'username':username, 'password':password}
- ### The super() call would be more modern but it doesn't work with the current Python version yet.
- #super(api, self).__init__(address, verbose=debug)
- ServerProxy.__init__(self, address,verbose=verbose)
- ### It is considered good practice to Identify the client talking to the server:
- self.ClientIdentify({ "ClientName" : NAME % prog_name, "ClientVersion" : VERSION, "ClientVendor" : VENDOR })
-
- def __getattr__(self,name):
- return _Method(self.__request, name)
-
- def __request (self, methodname, params):
- if methodname.replace(API_PREFIX,'') not in VALID_METHODS:
- stderr.write( UNKNOWN_METHOD_MESSAGE % {
- 'method': methodname.replace(API_PREFIX,''), 'api_prefix': API_PREFIX,
- 'api_version': SIPGATE_API_DOC_V, 'api_date': SIPGATE_API_DOC_D } )
- if len(params)>0 and not type(params[0]) is dict:
- raise TypeError(DICT_AS_PARAM_MESSAGE % methodname.replace(API_PREFIX,''))
- method_function = ServerProxy.__getattr__(self,methodname)
- try:
- result = method_function(params[0] if len(params)>0 and type(params[0]) is dict else dict())
- # cast the result dictionary to a SipgateResponse (custom dictionary):
- result = SipgateResponse(result)
- except Fault, e:
- raise SipgateAPIFault(e.faultCode, e.faultString)
- except ProtocolError, e:
- raise SipgateAPIProtocolError(e.url, e.errcode, e.errmsg, e.headers)
- except socket_error, (value,message):
- raise SipgateAPISocketError(value, message)
- return result
-
-##
-class SipgateResponse(dict):
- def __init__(self, response_dict):
- try:
- self.StatusCode, self.StatusString = int(response_dict['StatusCode']), response_dict['StatusString']
- self.success = self.StatusCode == 200
- except:
- raise TypeError(RESPONSE_NOT_A_DICTIONARY % response_dict)
- dict.__init__(self, response_dict)
-
-class _Method:
- # With the help of this class the api class does not
- # need to state explicitly the possible XML-RPC calls.
- def __init__(self, send, name):
- self.__send = send
- self.__name = API_PREFIX+name
- def __call__(self, *args):
- return self.__send(self.__name, args)
-
-### ------ now we define the exceptions that could occur ------
-
-class SipgateAPIException(Exception):
- pass
-
-class SipgateAPIFault(Fault, SipgateAPIException):
- # As this inherits from xmlrpclib.Fault it also has the
- # attributes faultCode and faultString.
- pass
-
-class SipgateAPIProtocolError(ProtocolError, SipgateAPIException):
- # As this inherits from xmlrpclib.ProtocolError it also has the
- # attributes errcode and errmsg.
- pass
-
-class SipgateAPISocketError(socket_error, SipgateAPIException):
- # As this inherits from socket.error it also has the
- # attributes .
- pass
-
-### ------ This section contains message strings -------
-
-UNKNOWN_METHOD_MESSAGE = "The method '%(method)s' for the API prefix '%(api_prefix)s' " + \
- "was called. This method, however, is currently not documented for the Sipgate API " + \
- "v%(api_version)s (%(api_date)s). Let's try but I've warned you.\n"
-DICT_AS_PARAM_MESSAGE = 'Please specify a dictionary as function call parameter for api.%s().'
-RESPONSE_NOT_A_DICTIONARY = 'The response "%s" does not seem to be a response from the ' + \
- 'Sipgate XML-RPC API.'
-
-### ------ This section contains constants of the Sipgate XML-RPC API -------
-
-# This constant represents the version of the currently implemented Sipgate API
-# ans is taken from the API description PDF:
-SIPGATE_API_DOC_V = '1.06'
-SIPGATE_API_DOC_D = 'August 21, 2007'
-
-# Sipgate basic and plus accounts must use this API URL:
-SIPGATE_API_URL = "https://%(username)s:%(password)s@samurai.sipgate.net/RPC2"
-# Sipgate one and team have a different URL: api.sipgate.net.
-# see
-API_PREFIX = 'samurai.'
-
-VALID_METHODS = [
- 'AccountStatementGet',
- 'BalanceGet',
- 'ClientIdentify',
- 'HistoryGetByDate',
- 'ItemizedEntriesGet',
- 'OwnUriListGet',
- 'PhonebookEntryGet',
- 'PhonebookListGet',
- 'RecommendedIntervalGet',
- 'ServerdataGet',
- 'SessionClose',
- 'SessionInitiate',
- 'SessionInitiateMulti',
- 'SessionStatusGet',
- 'TosListGet',
- 'TosListGet',
- 'UmSummaryGet',
- 'UserdataGreetingGet',
- 'UserdataSipGet',
-]
-
-SERVER_STATUS_CODES = {
- ### From Table A.1 and A.2 of the API docu: general server status codes
- 200: 'Method success',
- 400: 'Method not supported',
- 401: 'Request denied (no reason specified)',
- 402: 'Internal error',
- 403: 'Invalid arguments',
- 404: 'Resources exceeded (this MUST not be used to indicate parameters in error)',
- 405: 'Invalid parameter name',
- 406: 'Invalid parameter type',
- 407: 'Invalid parameter value',
- 408: 'Attempt to set a non-writable parameter',
- 409: 'Notification request rejected.',
- 410: 'Parameter exceeds maximum size.',
- 411: 'Missing parameter.',
- 412: 'Too many requests.',
- 500: 'Date out of range.',
- 501: 'Uri does not belong to user.',
- 502: 'Unknown type of service.',
- 503: 'Selected payment method failed.',
- 504: 'Selected currency not supported.',
- 505: 'Amount exceeds limit.',
- 506: 'Malformed SIP URI.',
- 507: 'URI not in list.',
- 508: 'Format is not valid E.164.',
- 509: 'Unknown status.',
- 510: 'Unknown ID.',
- 511: 'Invalid timevalue.',
- 512: 'Referenced session not found.',
- 513: 'Only single default per TOS allowed.',
- 514: 'Malformed VCARD format.',
- 515: 'Malformed PID format.',
- 516: 'Presence information not available.',
- 517: 'Invalid label name.',
- 518: 'Label not assigned.',
- 519: 'Label doesn’t exist.',
- 520: 'Parameter includes invalid characters.',
- 521: 'Bad password. (Rejected due to security concerns.)',
- 522: 'Malformed timezone format.',
- 523: 'Delay exceeds limit.',
- 524: 'Requested VPN type not available.',
- 525: 'Requested TOS not available.',
- 526: 'Unified messaging not available.',
- 527: 'URI not available for registration.',
-}
-
-TYPE_OF_SERVICE = {
- 'fax': 'pages', # fax transmission
- 'text': 'characters', # text message (e.g. "SMS")
- 'video': 'seconds', # video communication
- 'voice': 'seconds', # voice communication
-}
-
-
-class helpers (object):
- @staticmethod
- def FQTN(phone_number, default_country_code):
- """
- Assures phone numbers are in the form of a E164 Fully Qualified Telephone Number
- without the leading + sign.
- The alternative would be the Python port of Google's libphonenumber:
- https://github.com/daviddrysdale/python-phonenumbers
- """
- phone_number = phone_number.replace(' ','').replace('-','').replace('+','').replace('/','')
-
- ## number starting with 00 (so it's an international format)
- if re.compile("^00[1-9][0-9]*$").match(phone_number):
- return phone_number[2:]
-
- ## number starting with your country code (so it was already a FQTN):
- if re.compile("^"+default_country_code+"[1-9][0-9]*$").match(phone_number):
- return phone_number
-
- if re.compile("^0[1-9]*$").match(phone_number):
- return default_country_code+phone_number[1:]
-
- if re.compile("^[1-9]*$").match(phone_number):
- return phone_number
-
- raise TypeError("Couldn't parse this phone number: "+phone_number)
diff --git a/cgi/sniff.py b/cgi/sniff.py
deleted file mode 100755
index 1fdac92..0000000
--- a/cgi/sniff.py
+++ /dev/null
@@ -1,99 +0,0 @@
-#!/usr/bin/python
-
-__author__ = "Steffen Vogel"
-__copyright__ = "Copyright 2013, Steffen Vogel"
-__license__ = "GPLv3"
-__maintainer__ = "Steffen Vogel"
-__email__ = "post@steffenvogel.de"
-__status__ = "Prototype"
-
-"""
- This file is part of transWhat
-
- transWhat 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 3 of the License, or
- any later version.
-
- transwhat 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 transWhat. If not, see .
-"""
-
-import os
-import sys
-import cgi
-import cgitb
-import time
-import pycurl
-import StringIO
-import json
-import sipgate
-
-sys.path.insert(1, os.path.join(sys.path[0], '..'))
-
-from constants import *
-
-def send_sms(recipient, content):
- sg = sipgate.api(SIPGATE_USERNAME, SIPGATE_PASSWORD, 'transwhat')
-
- default_uri = 'sip:NULL@sipgate.net'
- for own_uri in sg.OwnUriListGet()['OwnUriList']:
- if own_uri['DefaultUri']:
- default_uri = own_uri['SipUri']
-
- # SessionInitiate may return the following server status codes in case of errors: 501, 502, 506, 520, 525
- return sg.SessionInitiate({'LocalUri': default_uri, 'RemoteUri': 'sip:%s@sipgate.de' % recipient, 'TOS': 'text', 'Content': content })
-
-def main():
- url = os.environ['SCRIPT_URI'] + '?' + os.environ['QUERY_STRING']
-
- writer = StringIO.StringIO()
- ch = pycurl.Curl()
-
- ch.setopt(pycurl.URL, url)
- ch.setopt(pycurl.USERAGENT, os.environ['HTTP_USER_AGENT'])
-
- ch.setopt(pycurl.WRITEFUNCTION, writer.write)
- ch.setopt(pycurl.SSL_VERIFYPEER, False)
- ch.setopt(pycurl.HEADER, True)
-
- ch.perform()
-
- response = writer.getvalue()
- headers, body = response.split("\r\n\r\n", 1)
- headers = headers.split("\n")
- preamble = headers.pop(0)
-
- code = preamble.split(" ", 2)[1]
- status = preamble.split(" ", 2)[2]
-
- print "Status: %s %s" % (code, status)
- for header in headers:
- print header
-
- print
- print body
-
- file = open(REQUESTS_FILE, "a")
- file.write("\n--- Time: %s\n>>> Request: %s\n<<< Reponse Headers:\n%s\nResponse Body:\n%s\n" % (time.strftime("%a, %d %b %Y %H:%M:%S"), url, "\n".join(headers), body))
- file.close()
-
- # send password via sms to requester
- if code == "200":
- parsed = json.loads(body)
- form = cgi.FieldStorage()
- cc = form.getfirst("cc")
- number = form.getfirst("in")
-
- if parsed.has_key('pw') and parsed.has_key('login'):
- send_sms(parsed['login'], parsed['pw'])
-
- ch.close()
-
-if __name__ == "__main__":
- main()
diff --git a/conf/apache.cfg b/conf/apache.cfg
deleted file mode 100644
index f5f1124..0000000
--- a/conf/apache.cfg
+++ /dev/null
@@ -1,63 +0,0 @@
-
- ServerAdmin webmaster@0l.de
- ServerName whatsapp.0l.de
-
- DocumentRoot /home/stv0g/files/whatsapp/transwhat/cgi
-
- Options FollowSymLinks
- AllowOverride None
-
-
- Options Indexes FollowSymLinks MultiViews +ExecCGI
- AllowOverride All
- Order allow,deny
- allow from all
- AddHandler cgi-script .py
-
-
- ErrorLog /home/stv0g/files/whatsapp/htdocs/error.log
- CustomLog /home/stv0g/files/whatsapp/htdocs/access.log combined
-
-
-
-
- ServerAdmin webmaster@0l.de
- ServerName whatsapp.0l.de
- ServerAlias v.whatsapp.net
-
- DocumentRoot /home/stv0g/files/whatsapp/transwhat/cgi
-
- Options FollowSymLinks
- AllowOverride None
-
-
- Options Indexes FollowSymLinks MultiViews +ExecCGI
- AllowOverride None
- Order allow,deny
- allow from all
- AddHandler cgi-script .py
-
-
- ErrorLog /home/stv0g/files/whatsapp/htdocs/error.log
- CustomLog /home/stv0g/files/whatsapp/htdocs/access.log combined
-
- LogLevel info
- # debug, info, notice, warn, error, crit, alert, emerg.
-
- # Rewrite
- RewriteEngine on
-
- RewriteCond %{REQUEST_FILENAME} !-f
- RewriteCond %{REQUEST_FILENAME} !-d
- RewriteRule (.*) /sniff.py/$1
-
- # SSL
- SSLEngine on
- SSLCertificateFile /home/stv0g/files/whatsapp/htdocs/whatsapp.crt
- SSLCertificateKeyFile /home/stv0g/files/whatsapp/htdocs/whatsapp.key
-
-
- SSLOptions +StdEnvVars
-
-
-
diff --git a/constants.py.sample b/constants.py.sample
index 9856612..958c2e9 100644
--- a/constants.py.sample
+++ b/constants.py.sample
@@ -31,10 +31,4 @@ BASE_PATH = "/opt/transwhat"
TOKEN_FILE = BASE_PATH + "/logs/tokens"
MOTD_FILE = BASE_PATH + "/conf/motd"
-REQUESTS_FILE = BASE_PATH + "/logs/requests"
-
-GOOGLE_CLIENT_ID = ""
-GOOGLE_CLIENT_SECRET = ""
-
-SIPGATE_USERNAME=""
-SIPGATE_PASSWORD=""
+REQUESTS_FILE = BASE_PATH + "/logs/requests"
\ No newline at end of file
diff --git a/googleclient.py b/googleclient.py
deleted file mode 100644
index 899bbd0..0000000
--- a/googleclient.py
+++ /dev/null
@@ -1,69 +0,0 @@
-__author__ = "Steffen Vogel"
-__copyright__ = "Copyright 2013, Steffen Vogel"
-__license__ = "GPLv3"
-__maintainer__ = "Steffen Vogel"
-__email__ = "post@steffenvogel.de"
-__status__ = "Prototype"
-
-"""
- This file is part of transWhat
-
- transWhat 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 3 of the License, or
- any later version.
-
- transwhat 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 transWhat. If not, see .
-"""
-
-import sys
-
-import gdata.gauth
-import gdata.contacts.client
-import gdata.contacts.data
-import atom.data
-
-from constants import *
-
-gdata.contacts.REL_MOBILE='http://schemas.google.com/g/2005#mobile'
-
-class GoogleClient():
-
- def __init__(self):
- self.client = gdata.contacts.client.ContactsClient()
- # self.token = gdata.gauth.OAuth2Token(
- # client_id = GOOGLE_CLIENT_ID,
- # client_secret = GOOGLE_CLIENT_SECRET,
- # scope = 'https://www.google.com/m8/feeds/contacts',
- # user_agent = 'whatTrans'
- # )
-
- def getTokenUrl(self, uri = 'urn:ietf:wg:oauth:2.0:oob'):
- return self.token.generate_authorize_url(redirect_uri=uri)
-
- def getContacts(self, request_token):
- access_token = self.token.get_access_token(request_token)
-
- self.token.authorize(self.client)
-
- numbers = { }
-
- feed = self.client.GetContacts()
- while feed:
- for i, entry in enumerate(feed.entry):
- for number in entry.phone_number:
- numbers[number.text] = entry.title.text
-
- next = feed.GetNextLink()
- if next:
- feed = self.client.GetContacts(next.href)
- else:
- break
-
- return numbers
diff --git a/utils.py b/utils.py
index c2e1ba6..69a0c44 100644
--- a/utils.py
+++ b/utils.py
@@ -22,23 +22,10 @@ __status__ = "Prototype"
along with transWhat. If not, see .
"""
-import urllib
-import json
import e4u
import base64
import hashlib
-def shorten(url):
- url = urllib.urlopen("http://d.0l.de/add.json?type=URL&rdata=%s" % urllib.quote(url))
- response = url.read()
- response = json.loads(response)
-
- for entry in response:
- if entry['type'] == 'success':
- host = entry['data'][0]['host']
- return "http://s.%s/%s" % (host['zone']['name'], host['punycode'])
-
-
def ago(secs):
periods = ["second", "minute", "hour", "day", "week", "month", "year", "decade"]
lengths = [60, 60, 24, 7,4.35, 12, 10]