Skip to content

Commit

Permalink
add the projects files
Browse files Browse the repository at this point in the history
  • Loading branch information
jsarasin committed Apr 18, 2016
1 parent 6dc0884 commit 37e2642
Show file tree
Hide file tree
Showing 7 changed files with 372 additions and 0 deletions.
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
.idea
*.pyc
sample.png
#thumbnails/*
#pictures/*

138 changes: 138 additions & 0 deletions catchat.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk, Pango, Gdk, GObject


import cc_chat
import cc_http
import urllib
import os

TARGET_TYPE_URI_LIST = 80

CCHttp = cc_http.cc_http()


def get_file_path_from_dnd_dropped_uri(uri):
# get the path to file
path = ""
if uri.startswith('file:\\\\\\'): # windows
path = uri[8:] # 8 is len('file:///')
elif uri.startswith('file://'): # nautilus, rox
path = uri[7:] # 7 is len('file://')
elif uri.startswith('file:'): # xffm
path = uri[5:] # 5 is len('file:')

path = urllib.url2pathname(path) # escape special chars
path = path.strip('\r\n\x00') # remove \r\n and NULL

return path


class MyWindow(Gtk.Window):
chatroom = cc_chat.cc_chat(CCHttp)

def __init__(self):

#########################
# Setup the main window
Gtk.Window.__init__(self, title="Chat")
self.set_border_width(5)
self.set_size_request(400, 700)
self.set_position(Gtk.WindowPosition.CENTER)

#############################
# Create the internal widgets

# Create the chat area box
self.box = Gtk.Box(spacing=5, orientation=Gtk.Orientation.VERTICAL)
self.add(self.box)

# Create the chat message area
self.chat_scrollwindow = Gtk.ScrolledWindow()
self.chat_scrollwindow.set_vexpand(True)
self.chat_scrollwindow.set_hexpand(False)

self.textview = Gtk.TextView()
self.textview.set_editable(False)
self.textview.set_buffer(self.chatroom.chat_history)
self.textview.set_cursor_visible(False)
self.textview.set_wrap_mode(Gtk.WrapMode.WORD_CHAR)

self.chat_scrollwindow.add(self.textview)
self.box.add(self.chat_scrollwindow)

# Create the text entry
self.entry = Gtk.Entry()
self.entry.connect("activate", self.on_entry_return)

GObject.timeout_add_seconds(2, self.update_chat)



#####################
# Setup the DND Files
self.textview.drag_dest_set(Gtk.DestDefaults.ALL, [Gtk.TargetEntry.new("text/uri-list", 0, 80)], Gdk.DragAction.COPY)
self.textview.drag_dest_add_text_targets();
self.textview.connect("drag-motion", self.drag_over)
self.textview.connect("drag-data-received", self.drag_drop_receive)

self.entry.drag_dest_set(Gtk.DestDefaults.ALL, [Gtk.TargetEntry.new("text/uri-list", 0, 80)], Gdk.DragAction.COPY)
self.entry.drag_dest_add_text_targets();
self.entry.connect("drag-motion", self.drag_over)
self.entry.connect("drag-data-received", self.drag_drop_receive)

self.box.add(self.entry)

self.scroll_to_bottom()


def scroll_to_bottom(self):
marky = self.chatroom.chat_history.get_mark("end" + str(self.chatroom.chat_range_end))
if(marky != None):
self.textview.scroll_to_mark(marky, 0, True, 0,0)

def on_entry_return(self, input):

if(self.entry.get_text() == ""):
self.update_chat();
return

self.chatroom.say(self.entry.get_text())
self.entry.set_text("")
self.chatroom.update()
self.scroll_to_bottom()

def drag_over(self, widget, context, x,y, time):
Gdk.drag_status(context, Gdk.DragAction.COPY, time)
return True

def update_chat(self):
#GObject.idle_add(self.update_chat_worker)
self.chatroom.update()
self.scroll_to_bottom()

return True



def drag_drop_receive(self, widget, context, x, y, selection, target_type, time):
if target_type == TARGET_TYPE_URI_LIST:
uri = selection.get_data().strip('\r\n\x00')
uri_splitted = uri.split() # we may have more than one file dropped
for uri in uri_splitted:
path = get_file_path_from_dnd_dropped_uri(uri)
if os.path.isfile(path): # is it file?
hash = self.chatroom.maybe_send_file_return_hash(path)
self.chatroom.say_picture(hash)
self.chatroom.update()
self.scroll_to_bottom()

#data = file(path).read()



win = MyWindow()
win.connect("delete-event", Gtk.main_quit)
win.show_all()
Gtk.main()
53 changes: 53 additions & 0 deletions cc_chat.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk

import cc_http
import cc_chatbubblerenderer

class cc_chat(object):
chat_history = Gtk.TextBuffer()
bubble_maker = None
cchttp = None
chatroom = 0
chat_range_start = 0
chat_range_end = 0

def __init__(self, cchttpv):
self.cchttp = cchttpv
self.bubble_maker = cc_chatbubblerenderer.ChatBubbleRenderer(cchttpv)
self.bubble_maker.setup_tags(self.chat_history)

reply = self.cchttp.get_chat_from_id_range(self.chatroom)

for message in reply['chat_log']:
self.add_message_bubble(message)

def add_message_bubble(self, message):
if (message['idchats'] < self.chat_range_start):
self.chat_range_start = message['idchats']
if (message['idchats'] > self.chat_range_end):
self.chat_range_end = message['idchats']

self.bubble_maker.get_bubble(message, self.chat_history)

def say(self, message):
self.cchttp.say(self.chatroom, message)

def say_picture(self, hash):
self.cchttp.say_picture(self.chatroom, hash)

def maybe_send_file_return_hash(self, filename):
md5 = self.cchttp.md5(filename)

if(self.cchttp.check_hash_exists(md5) == False ):
self.cchttp.send_file(self.chatroom, filename)

return md5


def update(self):
reply = self.cchttp.get_chat_from_id_range(self.chatroom, self.chat_range_end)
for message in reply['chat_log']:
self.add_message_bubble(message)

74 changes: 74 additions & 0 deletions cc_chatbubblerenderer.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk, Gdk, Pango, GdkPixbuf

import cc_pictures

class ChatBubbleRenderer(object):
sender_id = 0
sender_says_tag = Gtk.TextTag()
cchttp = None

def __init__(self, cchttpv):
self.cchttp = cchttpv
self.sender_id = self.cchttp.userid

def setup_tags(self, textbuffer):
#background="orange", justification=Gtk.Justification.RIGHT
textbuffer.create_tag("says", weight=Pango.Weight.BOLD)
textbuffer.create_tag("message", indent=10
)
textbuffer.create_tag("time-sent", variant=Pango.Variant.SMALL_CAPS,
scale=0.75,
wrap_mode_set=Gtk.WrapMode.NONE)


textbuffer.create_tag("bubble-left", paragraph_background="lightgreen",
right_margin=50)

textbuffer.create_tag("bubble-right", justification=Gtk.Justification.RIGHT,
paragraph_background="lightblue",
left_margin = 100,
direction=Gtk.TextDirection.RTL,
wrap_mode=Gtk.WrapMode.WORD_CHAR,
right_margin = 0)

def get_bubble(self, message, textbuffer):
#textbuffer.get_iter_at_mark()
insert_at = textbuffer.get_end_iter()

mark_begin = textbuffer.create_mark("begin" + str(message['idchats']), insert_at, True)
mark_end = textbuffer.create_mark("end" + str(message['idchats']), insert_at, False)

textbuffer.insert(insert_at, "\n")
textbuffer.insert_with_tags_by_name(insert_at, str(message['creator']) + " says:\n", "says")

# Just a normal text message
if(message['message_type'] == 0):
textbuffer.insert_with_tags_by_name(insert_at, message['message'] , "message")

# A fancy pants image message!
if (message['message_type'] == 1):
picture = cc_pictures.get_pixbuf_thumbnail_from_hash(self.cchttp, message['message'])
textbuffer.insert_pixbuf(insert_at, picture)

textbuffer.insert_with_tags_by_name(insert_at, "\nTime sent: " + message['msg_written'], "time-sent")



begm = textbuffer.get_iter_at_mark(mark_begin)
endm = textbuffer.get_iter_at_mark(mark_end)

if(message['creator'] == self.sender_id):
textbuffer.apply_tag_by_name("bubble-left", begm, endm)
else:
textbuffer.apply_tag_by_name("bubble-right", begm, endm)




# {u'msg_written': u'2016-04-16 23:50:00',
# u'message': u'hot dogs are ok i guess.',
# u'creator': 0,
# u'message_type': 0,
# u'idchats': 1}
78 changes: 78 additions & 0 deletions cc_http.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
# Interface to the catchat server http requests
import requests
import json
import datetime
import hashlib


class cc_http(object):
server_url = 'http://azenguard.com/CatChat/'
username='james'
password='computer'
userid=1

def md5(self, fname):
hash_md5 = hashlib.md5()
with open(fname, "rb") as f:
for chunk in iter(lambda: f.read(4096), b""):
hash_md5.update(chunk)
return hash_md5.hexdigest()

def get_chat_from_id_range(self, chat_id, after=0, before=""):
r = requests.post(self.server_url + 'getchat.php', data={ 'chatroom': str(chat_id),
'rangetype': "id",
'after': str(after),
'before': str(before)
} )
return json.loads(r.text)

def say(self, chat_id, message):
now = datetime.datetime.now()
r = requests.post(self.server_url + 'writechat.php', data={ 'chatroom': str(chat_id),
'message':message,
'msg_written': str(now),
'message_type' : 0,
'creator_id' : self.userid
})
def say_picture(self, chat_id, hash):
now = datetime.datetime.now()
r = requests.post(self.server_url + 'writechat.php', data={ 'chatroom': str(chat_id),
'message':hash,
'msg_written': str(now),
'message_type' : 1,
'creator_id' : self.userid
})

def send_file(self, chat_id, filename):
md5_file = self.md5(filename)
now = datetime.datetime.now()
files = {'userfile':open(filename, 'rb')}
datas = { 'creator_id':self.userid,
'msg_written': str(now),
'chatroom': str(chat_id),
}
r = requests.post(self.server_url + 'writechatfile.php', data=datas, files=files)

def check_hash_exists(self, hash):
datas = { 'hash':hash
}

r = requests.post(self.server_url + "check_hash_exists.php", data=datas)
reply = json.loads(r.text)

return reply['exists']

def get_picture_thumbnail(self, hash):
r = requests.post(self.server_url + "thumbnails/" + hash)

if(r.headers['content-type'] == "image/png"):
open("thumbnails/" + hash, 'wb').write(r.content)
return True
else:
print "get_picture_thumbnail failed!, Status Code: " + str(r.status_code) #+ str(r.headers.items()) + "\n"
return r.status_code
# text/plain
# image/png

#CaseInsensitiveDict({'content-length': '42790', 'accept-ranges': 'bytes', 'server': 'Apache/2.4.6 (CentOS) OpenSSL/1.0.1e-fips mod_fcgid/2.3.9 PHP/5.4.16', 'last-modified': 'Mon, 18 Apr 2016 08:49:53 GMT', 'etag': '"a726-530be71b95ffb"', 'date': 'Mon, 18 Apr 2016 08:52:44 GMT', 'content-type': 'image/png'})
#http://azenguard.com/CatChat/thumbnails/cc9f2d22efdd1a8a161860a27eadc72f
23 changes: 23 additions & 0 deletions cc_pictures.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk, Gdk, Pango, GdkPixbuf

import cc_http, os

def download_thumbnail_from_hash(cc_http_connection, hash):
return cc_http_connection.get_picture_thumbnail(hash)

def get_pixbuf_thumbnail_from_hash(cc_http_connection, hash):
# Do we already have the file?
cached_file_name = "thumbnails/" + hash

if os.path.isfile(cached_file_name) == False:
if download_thumbnail_from_hash(cc_http_connection, hash) == True:
picture = GdkPixbuf.Pixbuf.new_from_file(cached_file_name)
else:
picture = GdkPixbuf.Pixbuf.new_from_file("missing.png")
else:
picture = GdkPixbuf.Pixbuf.new_from_file(cached_file_name)


return picture
Binary file added missing.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 37e2642

Please sign in to comment.