Changeset 9465
- Timestamp:
- 04/15/08 07:32:45 (6 months ago)
- Location:
- branches/session_centric/src
- Files:
-
- 3 modified
-
common/connection_handlers.py (modified) (7 diffs)
-
session.py (modified) (6 diffs)
-
tictactoe.py (modified) (9 diffs)
Legend:
- Unmodified
- Added
- Removed
-
branches/session_centric/src/common/connection_handlers.py
r9459 r9465 1594 1594 1595 1595 msgtxt = msg.getBody() 1596 msghtml = msg.getXHTML()1597 1596 subject = msg.getSubject() # if not there, it's None 1598 1597 … … 1613 1612 jid = gajim.get_jid_without_resource(frm) 1614 1613 1615 encTag = msg.getTag('x', namespace = common.xmpp.NS_ENCRYPTED)1616 1614 # invitations 1617 1615 invite = None 1616 encTag = msg.getTag('x', namespace = common.xmpp.NS_ENCRYPTED) 1618 1617 1619 1618 if not encTag: … … 1621 1620 if invite and not invite.getTag('invite'): 1622 1621 invite = None 1623 1624 delayed = msg.getTag('x', namespace = common.xmpp.NS_DELAY) != None1625 msg_id = None1626 composing_xep = None1627 1622 1628 1623 # FIXME: Msn transport (CMSN1.2.1 and PyMSN0.10) do NOT RECOMMENDED … … 1640 1635 return 1641 1636 1642 form_node = None1643 for xtag in xtags:1644 if xtag.getNamespace() == common.xmpp.NS_DATA:1645 form_node = xtag1646 break1647 1648 chatstate = None1649 1650 # chatstates - look for chatstate tags in a message if not delayed1651 if not delayed:1652 composing_xep = False1653 children = msg.getChildren()1654 for child in children:1655 if child.getNamespace() == 'http://jabber.org/protocol/chatstates':1656 chatstate = child.getName()1657 composing_xep = 'XEP-0085'1658 break1659 # No XEP-0085 support, fallback to XEP-00221660 if not chatstate:1661 chatstate_child = msg.getTag('x', namespace = common.xmpp.NS_EVENT)1662 if chatstate_child:1663 chatstate = 'active'1664 composing_xep = 'XEP-0022'1665 if not msgtxt and chatstate_child.getTag('composing'):1666 chatstate = 'composing'1667 1668 # XEP-0172 User Nickname1669 user_nick = msg.getTagData('nick')1670 if not user_nick:1671 user_nick = ''1672 1673 1637 if encTag and self.USE_GPG: 1674 1638 encmsg = encTag.getData() … … 1684 1648 if mtype == 'error': 1685 1649 self.dispatch_error_message(msg, msgtxt, session, frm, tim, subject) 1686 1687 return1688 1650 elif mtype == 'groupchat': 1689 self.dispatch_gc_message(msg, subject, frm, msgtxt, jid, tim, msghtml) 1690 1691 return 1651 self.dispatch_gc_message(msg, subject, frm, msgtxt, jid, tim) 1692 1652 elif invite is not None: 1693 1653 self.dispatch_invite_message(invite, frm) 1694 1695 return1696 elif mtype == 'chat':1697 if not msg.getTag('body') and chatstate is None: # no <body>1698 return1699 1700 log_type = 'chat_msg_recv'1701 else: # it's a single message1702 log_type = 'single_msg_recv'1703 1704 mtype = 'normal'1705 1706 if session.is_loggable() and msgtxt:1707 try:1708 msg_id = gajim.logger.write(log_type, frm, msgtxt,1709 tim = tim, subject = subject)1710 except exceptions.PysqliteOperationalError, e:1711 self.dispatch('ERROR', (_('Disk Write Error'), str(e)))1712 1713 treat_as = gajim.config.get('treat_incoming_messages')1714 1715 if treat_as:1716 mtype = treat_as1717 1718 # XXX horrible hack1719 if isinstance(session, ChatControlSession):1720 session.received(frm, msgtxt, tim, encrypted, mtype, subject, chatstate,1721 msg_id, composing_xep, user_nick, msghtml, form_node)1722 1654 else: 1723 session.received(msg) 1655 # XXX horrible hack 1656 if isinstance(session, ChatControlSession): 1657 session.received(frm, msgtxt, tim, encrypted, subject, msg) 1658 else: 1659 session.received(msg) 1724 1660 # END messageCB 1725 1661 … … 1742 1678 1743 1679 # process and dispatch a groupchat message 1744 def dispatch_gc_message(self, msg, subject, frm, msgtxt, jid, tim , msghtml):1680 def dispatch_gc_message(self, msg, subject, frm, msgtxt, jid, tim): 1745 1681 has_timestamp = bool(msg.timestamp) 1746 1682 … … 1762 1698 return 1763 1699 1764 self.dispatch('GC_MSG', (frm, msgtxt, tim, has_timestamp, msg html,1700 self.dispatch('GC_MSG', (frm, msgtxt, tim, has_timestamp, msg.getXHTML(), 1765 1701 statusCode)) 1766 1702 -
branches/session_centric/src/session.py
r9459 r9465 1 1 from common import helpers 2 2 3 from common import exceptions 3 4 from common import gajim 4 5 from common import stanza_session 5 6 from common import contacts 6 7 8 import common.xmpp 9 7 10 import dialogs 8 11 … … 17 20 self.control = None 18 21 22 # extracts chatstate from a <message/> stanza 23 def get_chatstate(self, msg, msgtxt): 24 composing_xep = None 25 chatstate = None 26 27 # chatstates - look for chatstate tags in a message if not delayed 28 delayed = msg.getTag('x', namespace=common.xmpp.NS_DELAY) != None 29 if not delayed: 30 composing_xep = False 31 children = msg.getChildren() 32 for child in children: 33 if child.getNamespace() == 'http://jabber.org/protocol/chatstates': 34 chatstate = child.getName() 35 composing_xep = 'XEP-0085' 36 break 37 # No XEP-0085 support, fallback to XEP-0022 38 if not chatstate: 39 chatstate_child = msg.getTag('x', namespace = common.xmpp.NS_EVENT) 40 if chatstate_child: 41 chatstate = 'active' 42 composing_xep = 'XEP-0022' 43 if not msgtxt and chatstate_child.getTag('composing'): 44 chatstate = 'composing' 45 46 return (composing_xep, chatstate) 47 19 48 # dispatch a received <message> stanza 20 def received(self, full_jid_with_resource, message, tim, encrypted, msg_type, subject, chatstate, msg_id, composing_xep, user_nick, xhtml, form_node): 49 def received(self, full_jid_with_resource, msgtxt, tim, encrypted, subject, msg): 50 msg_type = msg.getType() 51 msg_id = None 52 53 # XEP-0172 User Nickname 54 user_nick = msg.getTagData('nick') 55 if not user_nick: 56 user_nick ='' 57 58 form_node = None 59 for xtag in msg.getTags('x'): 60 if xtag.getNamespace() == common.xmpp.NS_DATA: 61 form_node = xtag 62 break 63 64 composing_xep, chatstate = self.get_chatstate(msg, msgtxt) 65 66 xhtml = msg.getXHTML() 67 68 if msg_type == 'chat': 69 if not msg.getTag('body') and chatstate is None: 70 return 71 72 log_type = 'chat_msg_recv' 73 else: 74 log_type = 'single_msg_recv' 75 76 if self.is_loggable() and msgtxt: 77 try: 78 msg_id = gajim.logger.write(log_type, full_jid_with_resource, msgtxt, 79 tim=tim, subject=subject) 80 except exceptions.PysqliteOperationalError, e: 81 gajim.dispatch('ERROR', (_('Disk WriteError'), str(e))) 82 83 treat_as = gajim.config.get('treat_incoming_messages') 84 if treat_as: 85 msg_type = treat_as 21 86 22 87 jid = gajim.get_jid_without_resource(full_jid_with_resource) … … 66 131 # THIS MUST BE AFTER chatstates handling 67 132 # AND BEFORE playsound (else we ear sounding on chatstates!) 68 if not m essage: # empty message text133 if not msgtxt: # empty message text 69 134 return 70 135 … … 87 152 if pm: 88 153 nickname = resource 89 groupchat_control.on_private_message(nickname, m essage, array[2],154 groupchat_control.on_private_message(nickname, msgtxt, array[2], 90 155 xhtml, session, msg_id) 91 156 else: 92 self.roster_message(jid, m essage, tim, encrypted, msg_type,157 self.roster_message(jid, msgtxt, tim, encrypted, msg_type, 93 158 subject, resource, msg_id, user_nick, advanced_notif_num, 94 159 xhtml=xhtml, form_node=form_node) … … 96 161 nickname = gajim.get_name_from_jid(self.conn.name, jid) 97 162 # Check and do wanted notifications 98 msg = m essage163 msg = msgtxt 99 164 if subject: 100 165 msg = _('Subject: %s') % subject + '\n' + msg … … 112 177 if gajim.interface.remote_ctrl: 113 178 gajim.interface.remote_ctrl.raise_signal('NewMessage', 114 (self.conn.name, [full_jid_with_resource, m essage, tim,179 (self.conn.name, [full_jid_with_resource, msgtxt, tim, 115 180 encrypted, msg_type, subject, chatstate, msg_id, 116 181 composing_xep, user_nick, xhtml, form_node])) -
branches/session_centric/src/tictactoe.py
r9459 r9465 10 10 # implements <http://pidgin-games.sourceforge.net/xep/tictactoe.html#invite> 11 11 12 games_ns = 'http://jabber.org/protocol/games' 13 12 14 class InvalidMove(Exception): 13 15 pass … … 25 27 self.role_o = 'x' 26 28 29 self.send_invitation() 30 31 self.next_move_id = 1 32 self.received = self.wait_for_invite_response 33 34 def send_invitation(self): 27 35 msg = xmpp.Message() 28 36 29 37 invite = msg.NT.invite 30 invite.setNamespace( 'http://jabber.org/protocol/games')38 invite.setNamespace(games_ns) 31 39 32 40 game = invite.NT.game 33 game.setAttr('var', 'http://jabber.org/protocol/games/tictactoe')41 game.setAttr('var', games_ns + '/tictactoe') 34 42 35 43 x = xmpp.DataForm(typ='submit') … … 39 47 self.send(msg) 40 48 41 self.next_move_id = 1 42 self.state = 'sent_invite' 49 def read_invitation(self, msg): 50 invite = msg.getTag('invite', namespace=games_ns) 51 game = invite.getTag('game') 52 x = game.getTag('x', namespace='jabber:x:data') 53 54 form = xmpp.DataForm(node=x) 55 56 if form.getField('role'): 57 self.role_o = form.getField('role').getValues()[0] 58 else: 59 self.role_o = 'x' 60 61 if form.getField('rows'): 62 self.rows = int(form.getField('rows').getValues()[0]) 63 else: 64 self.rows = 3 65 66 if form.getField('cols'): 67 self.cols = int(form.getField('cols').getValues()[0]) 68 else: 69 self.cols = 3 70 71 if form.getField('strike'): 72 self.strike = int(form.getField('strike').getValues()[0]) 73 else: 74 self.strike = 3 43 75 44 76 # received an invitation 45 77 def invited(self, msg): 46 invite = msg.getTag('invite', namespace='http://jabber.org/protocol/games') 47 game = invite.getTag('game') 48 x = game.getTag('x', namespace='jabber:x:data') 49 50 form = xmpp.DataForm(node=x) 51 52 if form.getField('role'): 53 self.role_o = form.getField('role').getValues()[0] 54 55 if form.getField('rows'): 56 self.rows = int(form.getField('rows').getValues()[0]) 57 58 if form.getField('cols'): 59 self.cols = int(form.getField('cols').getValues()[0]) 60 61 # XXX 'strike' 62 63 if not hasattr(self, 'rows'): 64 self.rows = 3 65 66 if not hasattr(self, 'cols'): 67 self.cols = 3 78 self.read_invitation(msg) 79 80 # XXX prompt user 81 # "accept, reject, ignore" 68 82 69 83 # the number of the move about to be made 70 84 self.next_move_id = 1 71 85 86 # display the board 72 87 self.board = TicTacToeBoard(self, self.rows, self.cols) 73 88 … … 76 91 77 92 join = response.NT.join 78 join.setNamespace( 'http://jabber.org/protocol/games')93 join.setNamespace(games_ns) 79 94 80 95 self.send(response) 81 96 82 if not hasattr(self, 'role_o') orself.role_o == 'x':97 if self.role_o == 'x': 83 98 self.role_s = 'o' 84 self.role_o = 'x'85 99 86 100 self.their_turn() … … 92 106 93 107 def is_my_turn(self): 94 return self.state == 'get_input' 95 96 def received(self, msg): 97 # just sent an invitation, expecting a reply 98 if self.state == 'sent_invite': 99 if msg.getTag('join', namespace='http://jabber.org/protocol/games'): 100 self.board = TicTacToeBoard(self, self.rows, self.cols) 101 102 if self.role_s == 'x': 103 self.our_turn() 104 else: 105 self.their_turn() 106 107 return 108 109 # ignore messages unless we're expecting a move 110 if self.state != 'waiting': 111 return 112 113 turn = msg.getTag('turn', namespace='http://jabber.org/protocol/games') 114 108 # XXX not great semantics 109 return self.received == self.ignore 110 111 # just sent an invitation, expecting a reply 112 def wait_for_invite_response(self, msg): 113 if msg.getTag('join', namespace=games_ns): 114 self.board = TicTacToeBoard(self, self.rows, self.cols) 115 116 if self.role_s == 'x': 117 self.our_turn() 118 else: 119 self.their_turn() 120 121 elif msg.getTag('decline', namespace=games_ns): 122 self.XXX() 123 124 # silently ignores any received messages 125 def ignore(self, msg): 126 pass 127 128 def wait_for_move(self, msg): 129 turn = msg.getTag('turn', namespace=games_ns) 115 130 move = turn.getTag('move', namespace='http://jabber.org/protocol/games/tictactoe') 116 131 … … 129 144 return 130 145 131 # XXX check win conditions 132 133 self.next_move_id += 1 134 135 self.our_turn() 146 # check win conditions 147 if self.board.check_for_strike(self.role_o, row, col, self.strike): 148 self.lost() 149 elif self.board.full(): 150 self.drawn() 151 else: 152 self.next_move_id += 1 153 154 self.our_turn() 136 155 137 156 def our_turn(self): 138 self.state = 'get_input' 157 # ignore messages until we've made our move 158 self.received = self.ignore 139 159 self.board.win.set_title(self.board.title + ': your turn') 140 160 141 161 def their_turn(self): 142 self. state = 'waiting'162 self.received = self.wait_for_move 143 163 self.board.win.set_title(self.board.title + ': their turn') 144 164 145 165 # called when the board receives input 146 def move(self, row, col umn):166 def move(self, row, col): 147 167 try: 148 self.board.mark(row, col umn, self.role_s)168 self.board.mark(row, col, self.role_s) 149 169 except InvalidMove, e: 150 print ' invalid move'170 print 'you made an invalid move' 151 171 return 152 172 153 self.send_move(row, column) 154 155 # XXX check win conditions 173 self.send_move(row, col) 174 175 # check win conditions 176 if self.board.check_for_strike(self.role_s, row, col,self.strike): 177 self.won() 178 elif self.board.full(): 179 self.drawn() 180 else: 181 self.next_move_id += 1 182 183 self.their_turn() 156 184 157 185 def send_move(self, row, column): 158 186 msg = xmpp.Message() 187 msg.setType('chat') 159 188 160 189 turn = msg.NT.turn 161 turn.setNamespace( 'http://jabber.org/protocol/games')190 turn.setNamespace(games_ns) 162 191 163 192 move = turn.NT.move 164 move.setNamespace( 'http://jabber.org/protocol/games/tictactoe')193 move.setNamespace(games_ns+'/tictactoe') 165 194 166 195 move.setAttr('row', str(row)) … … 170 199 self.send(msg) 171 200 172 self.next_move_id += 1173 174 self.their_turn()175 176 201 class TicTacToeBoard: 202 def check_for_strike(self, p, r, c, strike): 203 # up and down, left and right 204 tallyI = 0 205 tally_ = 0 206 207 # right triangles: L\ , F/ 208 tallyL = 0 209 tallyF = 0 210 211 # convert real columns to internal columns 212 r -= 1 213 c -= 1 214 215 for d in xrange(-strike, strike): 216 # vertical check 217 try: 218 tallyI = tallyI + 1 if self.board[r+d][c] == p else 0 219 except IndexError: 220 pass 221 222 # horizontal check 223 try: 224 tally_ = tally_ + 1 if self.board[r][c+d] == p else 0 225 except IndexError: 226 pass 227 228 # diagonal checks 229 try: 230 tallyL = tallyL + 1 if self.board[r+d][c+d] == p else 0 231 except IndexError: 232 pass 233 234 try: 235 tallyF = tallyF + 1 if self.board[r+d][c-d] == p else 0 236 except IndexError: 237 pass 238 239 if any([t == strike for t in (tallyL, tallyF, tallyI, tally_)]): 240 return True 241 242 return False 243 177 244 def __init__(self, session, rows, cols): 178 245 self.session = session … … 184 251 185 252 self.setup_window() 253 254 # is the board full? 255 def full(self): 256 for r in xrange(self.rows): 257 for c in xrange(self.cols): 258 if self.board[r][c] == None: 259 return False 260 261 return True 186 262 187 263 def setup_window(self): … … 215 291 self.session.move(row, column) 216 292 293 # this actually draws the board 217 294 def expose(self, widget, event): 218 295 win = widget.window
