Commit 1cbd94ea authored by Philipp Hörist's avatar Philipp Hörist
Browse files

Add UserActivity (XEP-0107) module

parent bcf7fd1f
......@@ -370,3 +370,85 @@ MOODS = [
'undefined',
'weak',
'worried']
ACTIVITIES = {
'doing_chores': [
'buying_groceries',
'cleaning',
'cooking',
'doing_maintenance',
'doing_the_dishes',
'doing_the_laundry',
'gardening',
'running_an_errand',
'walking_the_dog'],
'drinking': [
'having_a_beer',
'having_coffee',
'having_tea'],
'eating': [
'having_a_snack',
'having_breakfast',
'having_dinner',
'having_lunch'],
'exercising': [
'cycling',
'dancing',
'hiking',
'jogging',
'playing_sports',
'running',
'skiing',
'swimming',
'working_out'],
'grooming': [
'at_the_spa',
'brushing_teeth',
'getting_a_haircut',
'shaving',
'taking_a_bath',
'taking_a_shower'],
'having_appointment': [],
'inactive': [
'day_off',
'hanging_out',
'hiding',
'on_vacation',
'praying',
'scheduled_holiday',
'sleeping',
'thinking'],
'relaxing': [
'fishing',
'gaming',
'going_out',
'partying',
'reading',
'rehearsing',
'shopping',
'smoking',
'socializing',
'sunbathing',
'watching_tv',
'watching_a_movie'],
'talking': [
'in_real_life',
'on_the_phone',
'on_video_phone'],
'traveling': [
'commuting',
'cycling',
'driving',
'in_a_car',
'on_a_bus',
'on_a_plane',
'on_a_train',
'on_a_trip',
'walking'],
'working': [
'coding',
'in_a_meeting',
'studying',
'writing']
}
\ No newline at end of file
......@@ -57,6 +57,7 @@ from nbxmpp.modules.captcha import Captcha
from nbxmpp.modules.entity_caps import EntityCaps
from nbxmpp.modules.blocking import Blocking
from nbxmpp.modules.pubsub import PubSub
from nbxmpp.modules.activity import Activity
from nbxmpp.modules.mood import Mood
from nbxmpp.modules.misc import unwrap_carbon
from nbxmpp.modules.misc import unwrap_mam
......@@ -183,6 +184,7 @@ class XMPPDispatcher(PlugIn):
self._modules['Blocking'] = Blocking(self._owner)
self._modules['PubSub'] = PubSub(self._owner)
self._modules['Mood'] = Mood(self._owner)
self._modules['Activity'] = Activity(self._owner)
for instance in self._modules.values():
for handler in instance.handlers:
......
# Copyright (C) 2018 Philipp Hörist <philipp AT hoerist.com>
#
# This file is part of nbxmpp.
#
# 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 3
# 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, see <http://www.gnu.org/licenses/>.
import logging
from nbxmpp.protocol import NS_ACTIVITY
from nbxmpp.protocol import NS_PUBSUB_EVENT
from nbxmpp.protocol import Node
from nbxmpp.structs import StanzaHandler
from nbxmpp.structs import ActivityData
from nbxmpp.const import ACTIVITIES
log = logging.getLogger('nbxmpp.m.activity')
class Activity:
def __init__(self, client):
self._client = client
self.handlers = [
StanzaHandler(name='message',
callback=self._process_pubsub_activity,
ns=NS_PUBSUB_EVENT,
priority=16),
]
def _process_pubsub_activity(self, _con, stanza, properties):
if not properties.is_pubsub_event:
return
if properties.pubsub_event.node != NS_ACTIVITY:
return
item = properties.pubsub_event.item
activity_node = item.getTag('activity', namespace=NS_ACTIVITY)
activity, subactivity, text = None, None, None
for child in activity_node.getChildren():
name = child.getName()
if name == 'text':
text = child.getData()
elif name in ACTIVITIES:
activity = name
subactivity = self._parse_sub_activity(child)
if activity is None and activity_node.getPayload():
log.warning('No valid activity value found')
log.warning(stanza)
return
data = ActivityData(activity, subactivity, text)
log.info('Received activity: %s - %s', properties.jid, data)
properties.pubsub_event = properties.pubsub_event._replace(data=data)
@staticmethod
def _parse_sub_activity(activity):
sub_activities = ACTIVITIES[activity.getName()]
for sub in activity.getChildren():
if sub.getName() in sub_activities:
return sub.getName()
def set_activity(self, data):
item = Node('activity', {'xmlns': NS_ACTIVITY})
if data is not None and data.activity:
activity_node = item.addChild(data.activity)
if data.subactivity:
activity_node.addChild(data.subactivity)
if data.text:
item.addChild('text', payload=data.text)
jid = self._client.get_bound_jid().getBare()
self._client.get_module('PubSub').publish(
jid, NS_ACTIVITY, item, id_='current')
......@@ -62,6 +62,8 @@ PubSubEventData = namedtuple('PubSubEventData', 'node id item data')
MoodData = namedtuple('MoodData', 'mood text')
ActivityData = namedtuple('ActivityData', 'activity subactivity text')
class MAMData(namedtuple('MAMData', 'id query_id archive namespace timestamp')):
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment