Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
leonjza committed Apr 20, 2015
1 parent 6e1de4f commit 533b6cb
Show file tree
Hide file tree
Showing 11 changed files with 432 additions and 0 deletions.
9 changes: 9 additions & 0 deletions MANIFEST
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# file GENERATED by distutils, do NOT edit
setup.cfg
setup.py
pytel/__init__.py
pytel/base.py
pytel/tg.py
pytel/utils/__init__.py
pytel/utils/sockets.py
pytel/utils/strings.py
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# PyTel
32 changes: 32 additions & 0 deletions example.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#!/usr/bin/env python

# The MIT License (MIT)
#
# Copyright (c) 2015 Leon Jacobs
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.

from pytel import tg

telegram = tg.Telegram('unix:///tmp/tg.sock')
# telegram = tg.Telegram('tcp://127.0.0.1:4444')

message = 'Dude! Whats mine say?'
telegram.send_message('Some Dude', message)
telegram.send_image('Some Dude', '/tmp/image.png')
Empty file added pytel/__init__.py
Empty file.
152 changes: 152 additions & 0 deletions pytel/base.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
# The MIT License (MIT)
#
# Copyright (c) 2015 Leon Jacobs
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.

from utils import sockets
import socket

class TelegramBase(object):

'''
TelegramBase
A python class to interface with a telegram-cli socket.
This is the parent class.
'''

# Connection specific properties
connection_type = None
location = None
port = None

# The socket connection
connection = None

def __init__(self, location):

'''
Prepare a new TG() instance
--
@param location:str The location of the TCP/Unix socket. Location
is broken up into 3 parts, of which the last
is optional. Examples are:
unix:///var/run/tg.sock
tcp://127.0.0.1:2931
@return None
'''

# Determine the socket type and location
# for the telegram-cli connection
if 'unix://' in location.lower():
self.connection_type = 'unix'

# strip the unix:// part. We also split by the
# port delimiter and choose the first key
# in case the port was accidentally
# specified.
self.location = location[7:].split(':')[0]

elif 'tcp://' in location.lower():
self.connection_type = 'tcp'

# Check that we have both a location and a port
# which will be delimited by a :
if len(location[6:].split(':')) != 2:
raise Exception('TCP Sockets should be specified in the format: tcp://host:port')

# strip the tcp:// part and set the location
# and port
self.location = location[6:].split(':')[0]
self.port = int(location[6:].split(':')[1])

else:
raise Exception('Unable to determine socket connection type. Expecting unix:// or tcp://')

return

def __del__(self):

'''
Desctruct the TG() instance
Cleans up the TG() instance by closing the socket connection
--
@return None
'''

if self.connection:
self.connection.close()

return

def _connect(self):

'''
Connect
Setup a socket connection to the specified telegram-cli socket
--
@return None
'''

if self.connection_type.lower() == 'tcp':
self.connection = sockets.setup_tcp_socket(self.location, self.port)

elif self.connection_type.lower() == 'unix':
self.connection = sockets.setup_domain_socket(self.location)

return

def _send(self, payload):

'''
Send
Send a payload to a telegram-cli socket.
--
@param payload:str The Payload to send over a socket connection.
@return bool
'''

if not self.connection:
self._connect()

# Send the payload, adding a newline to the end
self.connection.send(payload + '\n')

# Read 256 bytes off the socket and check the
# status that returned.
try:
data = self.connection.recv(256)

except socket.timeout, e:
print 'Failed to read response in a timely manner to determine the status.'
return False

if data.split('\n')[1] == 'FAIL':
print 'Failed to send payload: {payload}'.format(payload = payload)
return False

return True
99 changes: 99 additions & 0 deletions pytel/tg.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
# The MIT License (MIT)
#
# Copyright (c) 2015 Leon Jacobs
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.

from utils import strings
from pytel import base

class Telegram(base.TelegramBase):

'''
Telegram
A python class to interface with a telegram-cli socket.
This SubClass contains the commonly used methods.
'''

def raw(self, payload):

'''
Raw
Sends a a raw payload to the telegram-cli socket.
--
@param payload:str The Payload to send.
@return None
'''

self._send(payload)

return

def send_message(self, recipient, message):

'''
Send Message
Sends a message to a Telegram Recipient.
From telegram-cli:
msg <peer> <text> Sends text message to peer
--
@param recipient:str The telegram recipient the message is intended
for. Can be either a Person or a Group.
@param message:str The message to send.
@return None
'''

payload = 'msg {recipient} {message}'.format(
recipient = strings.escape_recipient(recipient),
message = strings.escape_newlines(message.strip())
)
self._send(payload)

return

def send_image(self, recipient, path):

'''
Send Image
Sends a an image to a Telegram Recipient. The image needs
to be readable to the telegram-cli instance where the
socket is created.
From telegram-cli:
send_photo <peer> <file> Sends photo to peer
--
@param recipient:str The telegram recipient the message is intended
for. Can be either a Person or a Group.
@param path:str The full path to the image to send.
@return None
'''

payload = 'send_photo {recipient} {path}'.format(
recipient = strings.escape_recipient(recipient),
path = path
)
self._send(payload)

return
Empty file added pytel/utils/__init__.py
Empty file.
68 changes: 68 additions & 0 deletions pytel/utils/sockets.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
# The MIT License (MIT)
#
# Copyright (c) 2015 Leon Jacobs
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.

import socket

'''
Sockets
Contains methods used to connect to Unix Domain or TCP sockets.
'''

timeout = 5

def setup_domain_socket(location):

'''
Setup Domain Socket
Setup a connection to a Unix Domain Socket
--
@param location:str The path to the Unix Domain Socket to connect to.
@return <class 'socket._socketobject'>
'''

clientsocket = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
clientsocket.settimeout(timeout)
clientsocket.connect(location)

return clientsocket

def setup_tcp_socket(location, port):

'''
Setup TCP Socket
Setup a connection to a TCP Socket
--
@param location:str The Hostname / IP Address of the remote TCP Socket.
@param port:int The TCP Port the remote Socket is listening on.
@return <class 'socket._socketobject'>
'''

clientsocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
clientsocket.settimeout(timeout)
clientsocket.connect((location, port))

return clientsocket
Loading

0 comments on commit 533b6cb

Please sign in to comment.