diff options
Diffstat (limited to 'dist/Honeypot.activity/gtk_honeypot.py')
-rwxr-xr-x | dist/Honeypot.activity/gtk_honeypot.py | 280 |
1 files changed, 280 insertions, 0 deletions
diff --git a/dist/Honeypot.activity/gtk_honeypot.py b/dist/Honeypot.activity/gtk_honeypot.py new file mode 100755 index 0000000..645f5c2 --- /dev/null +++ b/dist/Honeypot.activity/gtk_honeypot.py @@ -0,0 +1,280 @@ +#!/usr/bin/env python +# +# Copyright (C) 2010, Johannes Ponader +# +# 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. +# +# 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. +# +# 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 St, Fifth Floor, Boston, MA 02110-1301 USA + +from mathparse_honeypot import mathparse_honeypot +from xml_honeypot import xml_honeypot + +import gtk +import gtk.glade +import sys +import random +import time +import logging +import pango +import pygtk + +''' +try: + # should we use the treadsafe database module TS_Base?. + # although it is very unlikelike that a user runs two instances on his account, + # what would be the effect? + from buzhug import Base + +# as long as buzhug is a subdirectory of Honeypot.activity, import should be trivial +# do we want to install it anyway? would that be better for performance? +except ImportError: + + from distutils.core import setup + + # this command, esp. sys_args = 'install', is not tested yet + # perhaps run_setup('buzhug_setup', 'install') would be more clearly + + # btw, if we don't have the permission to install it into the standard location + # ('/usr/', i guess), we have to sudo the install or have to use the home dir instead? + # see http://docs.python.org/install/ + # what about win users using the script as standalone? + + setup(name='buzhug', + version='1.6', + description='Buzhug, a pure-Python database', + author='Pierre Quentel', + author_email='pierre.quentel@gmail.com', + url='http://buzhug.sourceforge.net/', + packages = ['buzhug'], + script_args = 'install') + + from buzhug import Base + +# if we don't have the permission to install it into the standard location +# ('/usr/', i guess), we have to sudo the install or have to use the home dir instead? +# see http://docs.python.org/install/ +# what about win users using the script as standalone? +''' + + +_logger = logging.getLogger('gtk_honeypot') + +# for logging outside sugar +if __name__ == '__main__': + LOG_FILENAME = 'logger.logfile' + logging.basicConfig(filename=LOG_FILENAME,level=logging.DEBUG) + +_logger.setLevel(logging.DEBUG) + +# Pango is a library for rendering internationalized texts + +pygtk.require('2.0') + +# load xml parser from xml_honeypot.py + + +# load mathparse parser from mathparse_honeypot.py + +# class guessfield(gtk_textfield): + +class gtk_honeypot: + + def __init__(self, runaslib=True): + + # Create DB, certainly, this goes into Journal afterwards, if it's not standalone + # not yet implemented + # path = '/home/olpc/Development/buzhug/' + # db = Base(path) + + + # Load glade xml + self.xml = gtk.glade.XML("gtk_honeypot.glade") + + # get window + self.window = self.xml.get_widget('window1') + self.window.connect("delete_event", gtk.main_quit) + + # get window child + self.window_child = self.window.get_child() + _logger.debug("self.window_child: " + str(self.window_child)) + + # get the label_button + self.label_question = self.xml.get_widget('label_question') + self.label_question.connect('clicked', self.on_label_question) + + # with self.textfield_answer as tf: + # funktioniert das? oder hat das seltame Nebeneffekte? + # am ende von with wid das objekt schliesslich aufgeraeumt... + + # get the textfield + self.textfield_answer = self.xml.get_widget('textfield_answer') + # self.textfield_answer.connect('clicked', self.on_guessed) + self.textfield_answer.connect('activate', self.on_textfield_answer_activate) + # self.textfield_answer.connect('move-cursor', self.on_textfield_answer_move_cursor) + + self.textfield_answer.handler_id = [] + # self.textfield.handler_id.append(self.textfield_answer.connect('insert-at-cursor', self.on_textfield_answer_insert_at_cursor)) + self.textfield_answer.handler_id.append(self.textfield_answer.connect('move-cursor', self.kill_event, 'move-cursor')) + self.textfield_answer.handler_id.append(self.textfield_answer.connect('delete-text', self.kill_event, 'delete-text')) + self.textfield_answer.handler_id.append(self.textfield_answer.connect('insert-text', self.on_textfield_answer_insert_text)) + # we need a get-focus or so event-handler, which sets the cursor right again in state STATE_WRONG + + self.textfield_answer.move_cursor_id = self.textfield_answer.handler_id[0] + # block these handlers for now + for i in range(0, len(self.textfield_answer.handler_id)): + self.textfield_answer.handler_block(self.textfield_answer.handler_id[i]) + + + + # self.textfield_answer.connect('event', self.on_textfield_answer_event) + # backspace, copy-clipboard, cut-clipboard, deleste-from-cursor, insert-at-cursor, move-cursor, paste-clipboard, + # changed, delete-text, insert-text + # gobject.stop_emission() + # key-press-event + # selection-clear-event, (selection-get-event), + # drag-. + + + # this is a dirty way to define the color, i suppose + # we should use the current stylemap + self.cursor_color_train = gtk.Entry().get_colormap().alloc_color("red") + self.cursor_color_answer = gtk.Entry().get_colormap().alloc_color("black") + + self.textfield_answer.modify_cursor(self.cursor_color_answer, self.cursor_color_answer) + + # get the button + self.button_guess = self.xml.get_widget('button_guess') + self.button_guess.connect('clicked', self.on_button_guess) + # self.button_guess.connect('activate', self.on_button_guess) + + # self.widget will be attached to the Activity + # this can be any gtk widget except a window + self.widget = self.window_child + + # Seed the random number generator + random.seed(time.time()) + + # load one or more collections of questions and answers + self.honeypot = xml_honeypot() + self.honeypot.load_drops() + + # load the mathpars parser + # note: there must be a parser regitration lateron, so that the script + # can determine which parsers are successfully loaded + self.mathparse = mathparse_honeypot() + + # we define four states: + # 'fresh', 'open', 'wrong', 'right' + self.STATE_FRESH = 0 + self.STATE_OPEN = 1 + self.STATE_WRONG = 2 + + # and safe the actual state in self.state + self.state = self.STATE_FRESH + + if not runaslib: + self.window.show_all() + gtk.main() + + + def on_textfield_answer_activate(self, *args): + + if self.state == self.STATE_FRESH: + self.open_new_question() + + elif self.state == self.STATE_OPEN: + self.check_answer() + + # we need no else, because we want to ignore RETURN in the state 'wrong' + + + + def on_textfield_answer_insert_text(self, *args): + + # insert-text(editable, new_text, text_length, position, data) + + if args[1] == self.drop[1][self.rewrite_position]: + self.rewrite_position += 1 + self.textfield_answer.handler_block(self.textfield_answer.move_cursor_id) + self.textfield_answer.set_position(self.rewrite_position) + self.textfield_answer.handler_unblock(self.textfield_answer.move_cursor_id) + + # we check if the user typed in the whole answer + # kann ich die endposition eleganter auslesen? + if self.textfield_answer.get_position() == len(self.drop[1]): + self.label_question.set_label(self.drop[0] + "\nThat's it.\nClick here or hit RETURN for another question.") + + for i in range(0, len(self.textfield_answer.handler_id)): + self.textfield_answer.handler_block(self.textfield_answer.handler_id[i]) + + self.state = self.STATE_FRESH + + self.textfield_answer.stop_emission('insert-text') + + + def kill_event(self, *args): + self.textfield_answer.stop_emission(args[len(args)-1]) + + def on_textfield_answer_event(self, *args): + if args[1].type not in (3, 10, 11, 2): + # GDK_MOTION_NOTIFY, GDK_ENTER_NOTIFY, GDK_LEAVE_NOTIFY, GDK_EXPOSE): + print(args[1].type) + + def on_button_guess(self, *args): + # self.textfield_answer.add_events() + # self.textfield_answer.set_editable(False) + + # self.textfield_answer.select_region(0,1) + pass + + + def on_label_question(self, *args): + self.open_new_question() + + def open_new_question(self): + self.drop = random.choice(self.honeypot.content_handler.drops) + _logger.debug('random choice: ' + str(self.drop)) + # we now take always the mathparse parser - + # choose the parser dynamically from xml-atribute lateron + # self.label_question.set_label("I'll ask some other question, dude: " + self.drop[0]) + self.drop = self.mathparse.parse(self.drop) + self.label_question.set_label("Question:\n" + self.drop[0]) + + self.textfield_answer.grab_focus() + self.textfield_answer.set_text('') + self.state = self.STATE_OPEN + + def check_answer(self): + if self.textfield_answer.get_text() == self.drop[1]: + # correct answer + self.label_question.set_label("Correct!\nClick here or hit RETURN for another question.") + self.state = self.STATE_FRESH + else: + # wrong answer + self.label_question.set_label(self.drop[0] + "\nYour answer:\n" + self.textfield_answer.get_text() + + "\nThis answer is wrong :-(\nRetype the correct answer\nand hit RETURN for the next question.") + + # write correct answer + self.textfield_answer.set_text(self.drop[1]) + self.rewrite_position = 0 + + # activate special handlers + for i in range(0, len(self.textfield_answer.handler_id)): + self.textfield_answer.handler_unblock(self.textfield_answer.handler_id[i]) + # self.textfield_answer.handler_unblock_by_func(self.on_textfield_answer_insert_text) + self.textfield_answer.modify_cursor(self.cursor_color_train, self.cursor_color_train) + self.state = self.STATE_WRONG + + +if __name__ == '__main__': + gtk_honeypot(False) |