summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormathieui <mathieui@mathieui.net>2013-03-11 23:06:52 +0100
committermathieui <mathieui@mathieui.net>2013-03-11 23:06:52 +0100
commitcec1151ecb577a270b9e1f0ae5eaa238d3269ae8 (patch)
treedad224100ca67d09301d6d2fc3d64b958b7acc54
parentd2d04162146e6df454d67a4e48ee6655af1d6c0a (diff)
downloadpoezio-cec1151ecb577a270b9e1f0ae5eaa238d3269ae8.tar.gz
poezio-cec1151ecb577a270b9e1f0ae5eaa238d3269ae8.tar.bz2
poezio-cec1151ecb577a270b9e1f0ae5eaa238d3269ae8.tar.xz
poezio-cec1151ecb577a270b9e1f0ae5eaa238d3269ae8.zip
Fix #1839 (User mood/activity)
- Added as always new theming variables: CHAR_ROSTER_MOOD, CHAR_ROSTER_ACTIVITY (a SNOWMAN!) COLOR_ROSTER_MOOD, COLOR_ROSTER_ACTIVITY - Added two new notification types in Theme.INFO_COLORS (mood/activity) - Added new configuration options: display_mood/activity/tune_notifications (those can be set for a specific JID) enable_user_tune/nick/activity/mood - Added /activity and /mood commands, with completions - Moved the old /activity to /last_activity - Details are show in the ContactInfoWin if there is room, or with "i" on a contact in the roster.
-rw-r--r--data/default_config.cfg22
-rw-r--r--doc/en/configure.txt49
-rw-r--r--src/connection.py12
-rw-r--r--src/contact.py2
-rw-r--r--src/core.py175
-rw-r--r--src/pep.py215
-rw-r--r--src/tabs.py39
-rw-r--r--src/theming.py6
-rw-r--r--src/windows.py17
9 files changed, 496 insertions, 41 deletions
diff --git a/data/default_config.cfg b/data/default_config.cfg
index cbab6f64..19f435bc 100644
--- a/data/default_config.cfg
+++ b/data/default_config.cfg
@@ -347,11 +347,29 @@ display_tune_notifications = false
# in the roster).
# If this is set to false, then the display_tune_notifications
# option will be ignored.
-receive_user_tune = true
+enable_user_tune = true
+
+# Display user mood notifications as information messages or not
+display_mood_notifications = false
+
+# Receive the mood notifications or not (in order to display informations
+# in the roster).
+# If this is set to false, then the display_mood_notifications
+# option will be ignored.
+enable_user_mood = true
+
+# Display user activity notifications as information messages or not
+display_activity_notifications = false
+
+# Receive the activity notifications or not (in order to display informations
+# in the roster).
+# If this is set to false, then the display_activity_notifications
+# option will be ignored.
+enable_user_activity = true
# If set to true, use the nickname broadcasted by the user if none has been
# set manually.
-use_pep_nick = true
+enable_user_nick = true
# if true, chat states will be sent to the people you are talking to.
# Chat states are, for example, messages informing that you are composing
diff --git a/doc/en/configure.txt b/doc/en/configure.txt
index ecd1fc40..a11b7e66 100644
--- a/doc/en/configure.txt
+++ b/doc/en/configure.txt
@@ -118,11 +118,40 @@ section of this documentation.
If set to true, notifications about the music your contacts listen to
will be displayed in the info buffer as 'Tune' messages.
+*display_mood_notifications*:: false
+
+ If set to true, notifications about the mood of your contacts
+ will be displayed in the info buffer as 'Mood' messages.
+
+*display_activity_notifications*:: false
+
+ If set to true, notifications about the current activity of your contacts
+ will be displayed in the info buffer as 'Activity' messages.
+
*display_user_color_in_join_part*:: false
If set to true, the color of the nick will be used in MUCs information
messages, instead of the default color from the theme.
+*enable_user_activity*:: true
+
+ Set this to false if you don’t want to receive the mood of your contacts
+ anymore.
+
+*enable_user_mood*:: true
+
+ Set this to false if you don’t want to receive the mood of your contacts
+ anymore.
+
+*enable_user_nick*:: true
+
+ Set to false if you don’t want your contacts to hint you their identity.
+
+*enable_user_tune*:: true
+
+ If this is set to false, you will no longer be subscribed to tune events,
+ and the display_tune_notifications option will be ignored.
+
*enable_vertical_tab_list*:: false
If true, a vertical list of tabs, with their name, is displayed on the left of
@@ -281,11 +310,6 @@ section of this documentation.
If the message takes more than one line, the popup will stay visible
two more second per additional lines.
-*receive_user_tune*:: true
-
- If this is set to false, you will no longer be subscribed to tune events,
- and the display_tune_notifications option will be ignored.
-
*remote_fifo_path*:: ./poezio.fifo
The path of the FIFO used to send the commands (see the exec_remote option).
@@ -543,11 +567,26 @@ bar = false
Disable the beeps triggered by this conversation. Works in MucTab,
PrivateTab and ConversationTab.
+*display_activity_notifications*:: false
+
+ If set to true, notifications about the current activity of your contacts
+ will be displayed in the info buffer as 'Activity' messages.
+
+*display_mood_notifications*:: false
+
+ If set to true, notifications about the mood of your contacts
+ will be displayed in the info buffer as 'Mood' messages.
+
*display_user_color_in_join_part*:: false
If set to true, the color of the nick will be used in MUCs information
messages, instead of the default color from the theme.
+*display_tune_notifications*:: false
+
+ If set to true, notifications about the music your contacts listen to
+ will be displayed in the info buffer as 'Tune' messages.
+
*hide_exit_join*:: -1
Exact same thing than hide_status_change, except that it concerns
diff --git a/src/connection.py b/src/connection.py
index d5a393c5..8565a616 100644
--- a/src/connection.py
+++ b/src/connection.py
@@ -72,10 +72,18 @@ class Connection(sleekxmpp.ClientXMPP):
self.register_plugin('xep_0115')
self.register_plugin('xep_0191')
- if config.get('receive_user_tune', 'true') != 'false':
+ if config.get('enable_user_tune', 'true') != 'false':
self.register_plugin('xep_0118')
- if config.get('use_pep_nick', 'true') != 'false':
+
+ if config.get('enable_user_nick', 'true') != 'false':
self.register_plugin('xep_0172')
+
+ if config.get('enable_user_mood', 'true') != 'false':
+ self.register_plugin('xep_0107')
+
+ if config.get('enable_user_activity', 'true') != 'false':
+ self.register_plugin('xep_0108')
+
if config.get('send_poezio_info', 'true') == 'true':
info = {'name':'poezio',
'version': options.version}
diff --git a/src/contact.py b/src/contact.py
index 46cf8e6f..8e6595db 100644
--- a/src/contact.py
+++ b/src/contact.py
@@ -68,6 +68,8 @@ class Contact(object):
self._name = ''
self.error = None
self.tune = {}
+ self.mood = ''
+ self.activity = ''
@property
def groups(self):
diff --git a/src/core.py b/src/core.py
index 1a53baa7..0b041f2d 100644
--- a/src/core.py
+++ b/src/core.py
@@ -20,6 +20,7 @@ from threading import Event
from datetime import datetime
from xml.etree import cElementTree as ET
+import pep
import common
import theming
import logging
@@ -230,7 +231,6 @@ class Core(object):
self.key_func.update(key_func)
# Add handlers
- self.xmpp.add_event_handler("user_tune_publish", self.on_tune_event)
self.xmpp.add_event_handler('connected', self.on_connected)
self.xmpp.add_event_handler('disconnected', self.on_disconnected)
self.xmpp.add_event_handler('no_auth', self.on_failed_auth)
@@ -260,8 +260,14 @@ class Core(object):
self.xmpp.add_event_handler("attention", self.on_attention)
self.xmpp.add_event_handler("ssl_cert", self.validate_ssl)
self.all_stanzas = Callback('custom matcher', connection.MatchAll(None), self.incoming_stanza)
- if config.get('use_pep_nick', 'true') != 'false':
+ if config.get('enable_user_tune', 'true') != 'false':
+ self.xmpp.add_event_handler("user_tune_publish", self.on_tune_event)
+ if config.get('enable_user_nick', 'true') != 'false':
self.xmpp.add_event_handler("user_nick_publish", self.on_nick_received)
+ if config.get('enable_user_mood', 'true') != 'false':
+ self.xmpp.add_event_handler("user_mood_publish", self.on_mood)
+ if config.get('enable_user_activity', 'true') != 'false':
+ self.xmpp.add_event_handler("user_activity_publish", self.on_activity)
self.xmpp.register_handler(self.all_stanzas)
self.initial_joins = []
@@ -2132,7 +2138,7 @@ class Core(object):
serv_list.add(serv)
return the_input.auto_completion(list(serv_list), ' ')
- def command_activity(self, arg):
+ def command_last_activity(self, arg):
"""
/activity <jid>
"""
@@ -2158,12 +2164,72 @@ class Core(object):
self.information(msg, 'Info')
jid = safeJID(arg)
if jid == '':
- return self.command_help('activity')
+ return self.command_help('last_activity')
self.xmpp.plugin['xep_0012'].get_last_activity(jid, block=False, callback=callback)
- def completion_activity(self, the_input):
+ def completion_last_activity(self, the_input):
return the_input.auto_completion([jid for jid in roster.jids()], '', quotify=False)
+ def command_mood(self, arg):
+ """
+ /mood [<mood> [text]]
+ """
+ args = common.shell_split(arg)
+ if not args:
+ return self.xmpp.plugin['xep_0107'].stop(block=False)
+ mood = args[0]
+ if mood not in pep.MOODS:
+ return self.information('%s is not a correct value for a mood.' % mood, 'Error')
+ if len(args) > 1:
+ text = args[1]
+ else:
+ text = None
+ self.xmpp.plugin['xep_0107'].publish_mood(mood, text, block=False)
+
+ def completion_mood(self, the_input):
+ """Completion for /mood"""
+ return the_input.auto_completion(list(pep.MOODS.keys()), '', quotify=False)
+
+ def command_activity(self, arg):
+ """
+ /activity [<general> [specific] [text]]
+ """
+ args = common.shell_split(arg)
+ length = len(args)
+ if not length:
+ return self.xmpp.plugin['xep_0108'].stop(block=False)
+ general = args[0]
+ if general not in pep.ACTIVITIES:
+ return self.information('%s is not a correct value for an activity' % general, 'Error')
+ specific = None
+ text = None
+ if length == 2:
+ if args[1] in pep.ACTIVITIES[general]:
+ specific = args[1]
+ else:
+ text = args[1]
+ elif length == 3:
+ specific = args[1]
+ text = args[2]
+ if specific and specific not in pep.ACTIVITIES[general]:
+ return self.information('%s is not a correct value for an activity' % specific, 'Error')
+ self.xmpp.plugin['xep_0108'].publish_activity(general, specific, text, block=False)
+
+ def completion_activity(self, the_input):
+ """Completion for /activity"""
+ txt = the_input.get_text()
+ args = common.shell_split(txt)
+ n = len(args)
+ if txt.endswith(' '):
+ n += 1
+ if n == 2:
+ return the_input.auto_completion(list(pep.ACTIVITIES.keys()), '', quotify=False)
+ elif n == 3:
+ if args[1] in pep.ACTIVITIES:
+ l = list(pep.ACTIVITIES[args[1]])
+ l.remove('category')
+ return the_input.auto_completion(l, '', quotify=False)
+
def command_invite(self, arg):
"""/invite <to> <room> [reason]"""
args = common.shell_split(arg)
@@ -2233,6 +2299,10 @@ class Core(object):
msg = arg
else:
msg = None
+ if config.get('enable_user_mood', 'true') != 'false':
+ self.xmpp.plugin['xep_0107'].stop(block=False)
+ if config.get('enable_user_activity', 'true') != 'false':
+ self.xmpp.plugin['xep_0108'].stop(block=False)
self.plugin_manager.disable_plugins()
self.disconnect(msg)
self.running = False
@@ -2489,11 +2559,25 @@ class Core(object):
completion=self.completion_runkey)
self.register_command('self', self.command_self,
shortdesc=_('Remind you of who you are.'))
- self.register_command('activity', self.command_activity,
+ self.register_command('last_activity', self.command_last_activity,
usage='<jid>',
desc=_('Informs you of the last activity of a JID.'),
shortdesc=_('Get the activity of someone.'),
- completion=self.completion_activity)
+ completion=self.completion_last_activity)
+ if config.get('enable_user_mood', 'true') != 'false':
+ self.register_command('activity', self.command_activity,
+ usage='[<general> [specific] [text]]',
+ desc=_('Send your current activity to your contacts (use the completion).'
+ ' Nothing means "stop broadcasting an activity".'),
+ shortdesc=_('Send your activity.'),
+ completion=self.completion_activity)
+ if config.get('eanble_user_activity', 'true') != 'false':
+ self.register_command('mood', self.command_mood,
+ usage='[<mood> [text]]',
+ desc=_('Send your current mood to your contacts (use the completion).'
+ ' Nothing means "stop broadcasting a mood".'),
+ shortdesc=_('Send your mood.'),
+ completion=self.completion_mood)
####################### XMPP Event Handlers ##################################
@@ -2555,7 +2639,7 @@ class Core(object):
else:
remote_nick = ''
# check for a received nick
- if not remote_nick and config.get('use_pep_nick', 'true') != 'false':
+ if not remote_nick and config.get('enable_user_nick', 'true') != 'false':
if message.xml.find('{http://jabber.org/protocol/nick}nick') is not None:
remote_nick = message['nick']['nick']
# bind the nick to the conversation
@@ -2633,6 +2717,68 @@ class Core(object):
item = message['pubsub_event']['items']['item']
if item.xml.find('{http://jabber.org/protocol/nick}nick') is not None:
contact.name = item['nick']['nick']
+ else:
+ contact.name= ''
+
+ def on_mood(self, message):
+ """
+ Called when a pep notification for an user mood
+ is received.
+ """
+ contact = roster[message['from'].bare]
+ if not contact:
+ return
+ item = message['pubsub_event']['items']['item']
+ if item.xml.find('{http://jabber.org/protocol/mood}mood') is not None:
+ mood = item['mood']['value']
+ if mood:
+ mood = pep.MOODS.get(mood, mood)
+ text = item['mood']['text']
+ if text:
+ mood = '%s (%s)' % (mood, text)
+ contact.mood = mood
+ else:
+ contact.mood = ''
+ else:
+ contact.mood = ''
+ if config.get_by_tabname('display_mood_notifications', 'false', contact.bare_jid) == 'true':
+ if contact.mood:
+ self.information('Mood from '+ contact.bare_jid + ': ' + contact.mood, 'Mood')
+ else:
+ self.information(contact.bare_jid + ' stopped having his/her mood.', 'Mood')
+
+ def on_activity(self, message):
+ """
+ Called when a pep notification for an user activity
+ is received.
+ """
+ contact = roster[message['from'].bare]
+ if not contact:
+ return
+ item = message['pubsub_event']['items']['item']
+ if item.xml.find('{http://jabber.org/protocol/activity}activity') is not None:
+ try:
+ activity = item['activity']['value']
+ except ValueError:
+ return
+ if activity[0]:
+ general = pep.ACTIVITIES.get(activity[0])
+ s = general['category']
+ if activity[1]:
+ s = s + '/' + general.get(activity[1], 'other')
+ text = item['activity']['text']
+ if text:
+ s = '%s (%s)' % (s, text)
+ contact.activity = s
+ else:
+ contact.activity = ''
+ else:
+ contact.activity = ''
+ if config.get_by_tabname('display_activity_notifications', 'false', contact.bare_jid) == 'true':
+ if contact.activity:
+ self.information('Activity from '+ contact.bare_jid + ': ' + contact.activity, 'Activity')
+ else:
+ self.information(contact.bare_jid + ' stopped doing his/her activity.', 'Activity')
def on_tune_event(self, message):
"""
@@ -2656,10 +2802,13 @@ class Core(object):
}
else:
contact.tune = {}
- if config.get('display_tune_notifications', 'false') == 'true' and contact.tune:
- self.information(
- 'Tune from '+ message['from'].bare + ': ' + common.format_tune_string(contact.tune),
- 'Tune')
+ if config.get_by_tabname('display_tune_notifications', 'false', contact.bare_jid) == 'true':
+ if contact.tune:
+ self.information(
+ 'Tune from '+ message['from'].bare + ': ' + common.format_tune_string(contact.tune),
+ 'Tune')
+ else:
+ self.information(contact.bare_jid + ' stopped listening to music.', 'Tune')
def on_groupchat_message(self, message):
"""
@@ -3068,7 +3217,7 @@ class Core(object):
status=self.status.message,
show=self.status.show)
- if config.get('use_pep_nick', 'true') != 'false':
+ if config.get('enable_user_nick', 'true') != 'false':
self.xmpp.plugin['xep_0172'].publish_nick(nick=self.own_nick)
### Other handlers ###
diff --git a/src/pep.py b/src/pep.py
new file mode 100644
index 00000000..e077a315
--- /dev/null
+++ b/src/pep.py
@@ -0,0 +1,215 @@
+# -*- coding:utf-8 -*-
+## src/common/pep.py
+##
+## Copyright (C) 2007 Piotr Gaczkowski <doomhammerng AT gmail.com>
+## Copyright (C) 2007-2012 Yann Leboulanger <asterix AT lagaule.org>
+## Copyright (C) 2008 Brendan Taylor <whateley AT gmail.com>
+## Jean-Marie Traissard <jim AT lapin.org>
+## Jonathan Schleifer <js-common.gajim AT webkeks.org>
+## Stephan Erb <steve-e AT h3c.de>
+##
+## This file is part of Gajim.
+##
+## Gajim 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; version 3 only.
+##
+## Gajim 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 Gajim. If not, see <http://www.gnu.org/licenses/>.
+##
+from gettext import gettext as _
+
+MOODS = {
+ 'afraid': _('Afraid'),
+ 'amazed': _('Amazed'),
+ 'amorous': _('Amorous'),
+ 'angry': _('Angry'),
+ 'annoyed': _('Annoyed'),
+ 'anxious': _('Anxious'),
+ 'aroused': _('Aroused'),
+ 'ashamed': _('Ashamed'),
+ 'bored': _('Bored'),
+ 'brave': _('Brave'),
+ 'calm': _('Calm'),
+ 'cautious': _('Cautious'),
+ 'cold': _('Cold'),
+ 'confident': _('Confident'),
+ 'confused': _('Confused'),
+ 'contemplative': _('Contemplative'),
+ 'contented': _('Contented'),
+ 'cranky': _('Cranky'),
+ 'crazy': _('Crazy'),
+ 'creative': _('Creative'),
+ 'curious': _('Curious'),
+ 'dejected': _('Dejected'),
+ 'depressed': _('Depressed'),
+ 'disappointed': _('Disappointed'),
+ 'disgusted': _('Disgusted'),
+ 'dismayed': _('Dismayed'),
+ 'distracted': _('Distracted'),
+ 'embarrassed': _('Embarrassed'),
+ 'envious': _('Envious'),
+ 'excited': _('Excited'),
+ 'flirtatious': _('Flirtatious'),
+ 'frustrated': _('Frustrated'),
+ 'grateful': _('Grateful'),
+ 'grieving': _('Grieving'),
+ 'grumpy': _('Grumpy'),
+ 'guilty': _('Guilty'),
+ 'happy': _('Happy'),
+ 'hopeful': _('Hopeful'),
+ 'hot': _('Hot'),
+ 'humbled': _('Humbled'),
+ 'humiliated': _('Humiliated'),
+ 'hungry': _('Hungry'),
+ 'hurt': _('Hurt'),
+ 'impressed': _('Impressed'),
+ 'in_awe': _('In Awe'),
+ 'in_love': _('In Love'),
+ 'indignant': _('Indignant'),
+ 'interested': _('Interested'),
+ 'intoxicated': _('Intoxicated'),
+ 'invincible': _('Invincible'),
+ 'jealous': _('Jealous'),
+ 'lonely': _('Lonely'),
+ 'lost': _('Lost'),
+ 'lucky': _('Lucky'),
+ 'mean': _('Mean'),
+ 'moody': _('Moody'),
+ 'nervous': _('Nervous'),
+ 'neutral': _('Neutral'),
+ 'offended': _('Offended'),
+ 'outraged': _('Outraged'),
+ 'playful': _('Playful'),
+ 'proud': _('Proud'),
+ 'relaxed': _('Relaxed'),
+ 'relieved': _('Relieved'),
+ 'remorseful': _('Remorseful'),
+ 'restless': _('Restless'),
+ 'sad': _('Sad'),
+ 'sarcastic': _('Sarcastic'),
+ 'satisfied': _('Satisfied'),
+ 'serious': _('Serious'),
+ 'shocked': _('Shocked'),
+ 'shy': _('Shy'),
+ 'sick': _('Sick'),
+ 'sleepy': _('Sleepy'),
+ 'spontaneous': _('Spontaneous'),
+ 'stressed': _('Stressed'),
+ 'strong': _('Strong'),
+ 'surprised': _('Surprised'),
+ 'thankful': _('Thankful'),
+ 'thirsty': _('Thirsty'),
+ 'tired': _('Tired'),
+ 'undefined': _('Undefined'),
+ 'weak': _('Weak'),
+ 'worried': _('Worried')}
+
+ACTIVITIES = {
+ 'doing_chores': {'category': _('Doing Chores'),
+ 'buying_groceries': _('Buying Groceries'),
+ 'cleaning': _('Cleaning'),
+ 'cooking': _('Cooking'),
+ 'doing_maintenance': _('Doing Maintenance'),
+ 'doing_the_dishes': _('Doing the Dishes'),
+ 'doing_the_laundry': _('Doing the Laundry'),
+ 'gardening': _('Gardening'),
+ 'running_an_errand': _('Running an Errand'),
+ 'walking_the_dog': _('Walking the Dog')},
+ 'drinking': {'category': _('Drinking'),
+ 'having_a_beer': _('Having a Beer'),
+ 'having_coffee': _('Having Coffee'),
+ 'having_tea': _('Having Tea')},
+ 'eating': {'category': _('Eating'),
+ 'having_a_snack': _('Having a Snack'),
+ 'having_breakfast': _('Having Breakfast'),
+ 'having_dinner': _('Having Dinner'),
+ 'having_lunch': _('Having Lunch')},
+ 'exercising': {'category': _('Exercising'),
+ 'cycling': _('Cycling'),
+ 'dancing': _('Dancing'),
+ 'hiking': _('Hiking'),
+ 'jogging': _('Jogging'),
+ 'playing_sports': _('Playing Sports'),
+ 'running': _('Running'),
+ 'skiing': _('Skiing'),
+ 'swimming': _('Swimming'),
+ 'working_out': _('Working out')},
+ 'grooming': {'category': _('Grooming'),
+ 'at_the_spa': _('At the Spa'),
+ 'brushing_teeth': _('Brushing Teeth'),
+ 'getting_a_haircut': _('Getting a Haircut'),
+ 'shaving': _('Shaving'),
+ 'taking_a_bath': _('Taking a Bath'),
+ 'taking_a_shower': _('Taking a Shower')},
+ 'having_appointment': {'category': _('Having an Appointment')},
+ 'inactive': {'category': _('Inactive'),
+ 'day_off': _('Day Off'),
+ 'hanging_out': _('Hanging out'),
+ 'hiding': _('Hiding'),
+ 'on_vacation': _('On Vacation'),
+ 'praying': _('Praying'),
+ 'scheduled_holiday': _('Scheduled Holiday'),
+ 'sleeping': _('Sleeping'),
+ 'thinking': _('Thinking')},
+ 'relaxing': {'category': _('Relaxing'),
+ 'fishing': _('Fishing'),
+ 'gaming': _('Gaming'),
+ 'going_out': _('Going out'),
+ 'partying': _('Partying'),
+ 'reading': _('Reading'),
+ 'rehearsing': _('Rehearsing'),
+ 'shopping': _('Shopping'),
+ 'smoking': _('Smoking'),
+ 'socializing': _('Socializing'),
+ 'sunbathing': _('Sunbathing'),
+ 'watching_tv': _('Watching TV'),
+ 'watching_a_movie': _('Watching a Movie')},
+ 'talking': {'category': _('Talking'),
+ 'in_real_life': _('In Real Life'),
+ 'on_the_phone': _('On the Phone'),
+ 'on_video_phone': _('On Video Phone')},
+ 'traveling': {'category': _('Traveling'),
+ 'commuting': _('Commuting'),
+ 'cycling': _('Cycling'),
+ 'driving': _('Driving'),
+ 'in_a_car': _('In a Car'),
+ 'on_a_bus': _('On a Bus'),
+ 'on_a_plane': _('On a Plane'),
+ 'on_a_train': _('On a Train'),
+ 'on_a_trip': _('On a Trip'),
+ 'walking': _('Walking')},
+ 'working': {'category': _('Working'),
+ 'coding': _('Coding'),
+ 'in_a_meeting': _('In a Meeting'),
+ 'studying': _('Studying'),
+ 'writing': _('Writing')}}
+
+LOCATION_DATA = {
+ 'accuracy': _('accuracy'),
+ 'alt': _('alt'),
+ 'area': _('area'),
+ 'bearing': _('bearing'),
+ 'building': _('building'),
+ 'country': _('country'),
+ 'countrycode': _('countrycode'),
+ 'datum': _('datum'),
+ 'description': _('description'),
+ 'error': _('error'),
+ 'floor': _('floor'),
+ 'lat': _('lat'),
+ 'locality': _('locality'),
+ 'lon': _('lon'),
+ 'postalcode': _('postalcode'),
+ 'region': _('region'),
+ 'room': _('room'),
+ 'speed': _('speed'),
+ 'street': _('street'),
+ 'text': _('text'),
+ 'timestamp': _('timestamp'),
+ 'uri': _('uri')}
diff --git a/src/tabs.py b/src/tabs.py
index 3805a690..ed2a5998 100644
--- a/src/tabs.py
+++ b/src/tabs.py
@@ -2076,7 +2076,7 @@ class RosterInfoTab(Tab):
self.key_func["M-Y"] = self.move_cursor_to_prev_group
self.key_func["M-[1;5B"] = self.move_cursor_to_next_group
self.key_func["M-[1;5A"] = self.move_cursor_to_prev_group
- self.key_func["l"] = self.command_activity
+ self.key_func["l"] = self.command_last_activity
self.key_func["o"] = self.toggle_offline_show
self.key_func["v"] = self.get_contact_version
self.key_func["i"] = self.show_contact_info
@@ -2139,11 +2139,11 @@ class RosterInfoTab(Tab):
completion=self.completion_file)
self.register_command('clear_infos', self.command_clear_infos,
shortdesc=_('Clear the info buffer.'))
- self.register_command('activity', self.command_activity,
+ self.register_command('last_activity', self.command_last_activity,
usage=_('<jid>'),
desc=_('Informs you of the last activity of a JID.'),
shortdesc=_('Get the activity of someone.'),
- completion=self.core.completion_activity)
+ completion=self.core.completion_last_activity)
self.core.xmpp.add_event_handler('session_start',
lambda event: self.core.xmpp.plugin['xep_0030'].get_info(
jid=self.core.xmpp.boundjid.domain,
@@ -2274,11 +2274,10 @@ class RosterInfoTab(Tab):
"""
self.core.disconnect()
- def command_activity(self, arg=None):
+ def command_last_activity(self, arg=None):
"""
/activity [jid]
"""
-
item = self.roster_win.selected_row
if arg:
jid = arg
@@ -2289,7 +2288,7 @@ class RosterInfoTab(Tab):
else:
self.core.information('No JID selected.', 'Error')
return
- self.core.command_activity(jid)
+ self.core.command_last_activity(jid)
def resize(self):
if not self.visible:
@@ -2845,14 +2844,18 @@ class RosterInfoTab(Tab):
if isinstance(selected_row, Contact):
cont = selected_row
res = selected_row.get_highest_priority_resource()
- msg = 'Contact: %s (%s)\n%s connected resource%s\nCurrent status: %s\nCurrent tune: %s' % (
- cont.bare_jid,
- res.presence if res else 'unavailable',
- len(cont),
- '' if len(cont) == 1 else 's',
- res.status if res else '',
- common.format_tune_string(cont.tune),
- )
+ acc = []
+ acc.append('Contact: %s (%s)' % (cont.bare_jid, res.presence if res else 'unavailable'))
+ if res:
+ acc.append('%s connected resource%s' % (len(cont), '' if len(cont) == 1 else 's'))
+ acc.append('Current status: %s' % res.status)
+ if cont.tune:
+ acc.append('Tune: %s' % common.format_tune_string(cont.tune))
+ if cont.mood:
+ acc.append('Mood: %s' % cont.mood)
+ if cont.activity:
+ acc.append('Activity: %s' % cont.activity)
+ msg = '\n'.join(acc)
elif isinstance(selected_row, Resource):
res = selected_row
msg = 'Resource: %s (%s)\nCurrent status: %s\nPriority: %s' % (
@@ -2959,11 +2962,11 @@ class ConversationTab(ChatTab):
shortdesc=_('Get the software version of the user.'))
self.register_command('info', self.command_info,
shortdesc=_('Get the status of the contact.'))
- self.register_command('activity', self.command_activity,
+ self.register_command('last_activity', self.command_last_activity,
usage=_('[jid]'),
desc=_('Get the last activity of the given or the current contact.'),
shortdesc=_('Get the activity.'),
- completion=self.core.completion_activity)
+ completion=self.core.completion_last_activity)
self.resize()
self.update_commands()
self.update_keys()
@@ -3023,12 +3026,12 @@ class ConversationTab(ChatTab):
self.text_win.refresh()
self.input.refresh()
- def command_activity(self, arg):
+ def command_last_activity(self, arg):
"""
/activity [jid]
"""
if arg.strip():
- return self.core.command_activity(arg)
+ return self.core.command_last_activity(arg)
def callback(iq):
if iq['type'] != 'result':
diff --git a/src/theming.py b/src/theming.py
index b95596c2..26b66377 100644
--- a/src/theming.py
+++ b/src/theming.py
@@ -202,7 +202,11 @@ class Theme(object):
CHAR_ROSTER_ERROR = '✖'
CHAR_ROSTER_TUNE = '♪'
CHAR_ROSTER_ASKED = '?'
+ CHAR_ROSTER_ACTIVITY = '☃'
+ CHAR_ROSTER_MOOD = '☺'
+ COLOR_ROSTER_MOOD = (2, -1)
+ COLOR_ROSTER_ACTIVITY = (3, -1)
COLOR_ROSTER_TUNE = (6, -1)
COLOR_ROSTER_ERROR = (1, -1)
COLOR_JOIN_CHAR = (4, -1)
@@ -221,6 +225,8 @@ class Theme(object):
'help': (10, -1),
'headline': (11, -1, 'b'),
'tune': (6, -1),
+ 'mood': (2, -1),
+ 'activity': (3, -1),
'default': (7, -1),
}
diff --git a/src/windows.py b/src/windows.py
index 78b3c5e5..c4927a6d 100644
--- a/src/windows.py
+++ b/src/windows.py
@@ -1938,6 +1938,10 @@ class RosterWin(Win):
added += len(get_theme().CHAR_ROSTER_ERROR)
if contact.tune:
added += len(get_theme().CHAR_ROSTER_TUNE)
+ if contact.mood:
+ added += len(get_theme().CHAR_ROSTER_MOOD)
+ if contact.activity:
+ added += len(get_theme().CHAR_ROSTER_ACTIVITY)
if config.getl('show_roster_jids', 'true') == 'false' and contact.name:
display_name = '%s' % contact.name
@@ -1958,7 +1962,10 @@ class RosterWin(Win):
self.addstr(get_theme().CHAR_ROSTER_ERROR, to_curses_attr(get_theme().COLOR_ROSTER_ERROR))
if contact.tune:
self.addstr(get_theme().CHAR_ROSTER_TUNE, to_curses_attr(get_theme().COLOR_ROSTER_TUNE))
-
+ if contact.activity:
+ self.addstr(get_theme().CHAR_ROSTER_ACTIVITY, to_curses_attr(get_theme().COLOR_ROSTER_ACTIVITY))
+ if contact.mood:
+ self.addstr(get_theme().CHAR_ROSTER_MOOD, to_curses_attr(get_theme().COLOR_ROSTER_MOOD))
self.finish_line()
def draw_resource_line(self, y, resource, colored):
@@ -2028,6 +2035,14 @@ class ContactInfoWin(Win):
self.addstr(i, 0, 'Current Tune: %s' % common.format_tune_string(contact.tune), to_curses_attr(get_theme().COLOR_NORMAL_TEXT))
i += 1
+ if contact.mood:
+ self.addstr(i, 0, 'Mood: %s' % contact.mood, to_curses_attr(get_theme().COLOR_NORMAL_TEXT))
+ i += 1
+
+ if contact.activity:
+ self.addstr(i, 0, 'Activity: %s' % contact.activity, to_curses_attr(get_theme().COLOR_NORMAL_TEXT))
+ i += 1
+
def draw_group_info(self, group):
"""
draw the group information