<commit_before>/*
 * TNWindowAddContact.j
 *
 * Copyright (C) 2010 <NAME> <<EMAIL>>
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero 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 Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

@import <Foundation/Foundation.j>

@import <AppKit/CPButton.j>
@import <AppKit/CPButton.j>
@import <AppKit/CPTextField.j>
@import <AppKit/CPWindow.j>

@import <TNKit/TNAlert.j>

@import <StropheCappuccino/PubSub/TNPubSubController.j>
@import <StropheCappuccino/TNStropheIMClient.j>

/*! @ingroup archipelcore
    subclass of CPWindow that allows to add a TNStropheContact
*/
@implementation TNContactsController: CPObject
{
    @outlet CPButton        buttonAdd;
    @outlet CPButton        buttonCancel;
    @outlet CPPopover       mainPopover;
    @outlet CPTextField     newContactJID;
    @outlet CPTextField     newContactName;

    TNPubSubController      _pubsubController   @accessors(property=pubSubController);

    CPDictionary            _localAvatars;
}

#pragma mark -
#pragma mark Initialization

- (void)awakeFromCib
{
    _localAvatars = [CPDictionary dictionary];

    var bundle = [CPBundle mainBundle];

    [_localAvatars setObject:[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"Avatars/RemoteAvatars/defaultvm.png"]] forKey:@"vm"];
    [_localAvatars setObject:[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"Avatars/RemoteAvatars/defaulthypervisor.png"]] forKey:@"hypervisor"];

    [[CPNotificationCenter defaultCenter] addObserver:self selector:@selector(_performPushRosterAdded:) name:TNStropheRosterPushAddedContactNotification object:nil];
    [[CPNotificationCenter defaultCenter] addObserver:self selector:@selector(_performPushRosterRemoved:) name:TNStropheRosterPushRemovedContactNotification object:nil];
    [[CPNotificationCenter defaultCenter] addObserver:self selector:@selector(_performPushRosterUpdated:) name:TNStropheRosterPushUpdatedContactNotification object:nil];
    [[CPNotificationCenter defaultCenter] addObserver:self selector:@selector(_didRecieveContactVCard:) name:TNStropheContactVCardReceivedNotification object:nil];

    [newContactName setToolTip:CPLocalizedString(@"The display name of the new contact", @"The display name of the new contact")];
    [newContactJID setToolTip:CPLocalizedString(@"The XMPP JID of the contact", @"The XMPP JID of the contact")];
}

#pragma mark -
#pragma mark Utilities

- (void)subscribeToPubSubNodeOfContactWithJID:(TNStropheJID)aJID
{
    var roster = [[TNStropheIMClient defaultClient] roster];
    if ([roster analyseVCard:[[roster contactWithJID:aJID] vCard]] == TNArchipelEntityTypeUser)
        return;

    var nodeName = @"/archipel/" + [aJID bare] + @"/events",
        server = [TNStropheJID stropheJIDWithString:@"pubsub." + [aJID domain]];

    if (![_pubsubController nodeWithName:nodeName])
        [_pubsubController subscribeToNodeWithName:nodeName server:server];
}

- (void)unsubscribeToPubSubNodeOfContactWithJID:(TNStropheJID)aJID
{
    var roster = [[TNStropheIMClient defaultClient] roster];
    if ([roster analyseVCard:[[roster contactWithJID:aJID] vCard]] == TNArchipelEntityTypeUser)
        return;

    var nodeName = "/archipel/" + [aJID bare] + "/events",
        server = [TNStropheJID stropheJIDWithString:@"pubsub." + [aJID domain]];

    if ([_pubsubController nodeWithName:nodeName])
        [_pubsubController unsubscribeFromNodeWithName:nodeName server:server]
}

- (void)addContact
{
    var JID     = [TNStropheJID stropheJIDWithString:[newContactJID stringValue]],
        name    = [newContactName stringValue];

    if (![JID node] || ![JID domain] || [JID resource])
    {
        [TNAlert showAlertWithMessage:CPLocalizedString(@"JID is not valid", @"JID is not valid")
                          informative:CPLocalizedString(@"You must enter a JID using the form user@domain.", @"You must enter a JID using the form user@domain.")
                                style:CPCriticalAlertStyle];
        return;
    }
    [[[TNStropheIMClient defaultClient] roster] addContact:JID withName:name inGroupWithPath:nil];
<commit_msg>detect JID with space as invalide. close #439<commit_after>/*
 * TNWindowAddContact.j
 *
 * Copyright (C) 2010 <NAME> <<EMAIL>>
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero 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 Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

@import <Foundation/Foundation.j>

@import <AppKit/CPButton.j>
@import <AppKit/CPButton.j>
@import <AppKit/CPTextField.j>
@import <AppKit/CPWindow.j>

@import <TNKit/TNAlert.j>

@import <StropheCappuccino/PubSub/TNPubSubController.j>
@import <StropheCappuccino/TNStropheIMClient.j>

/*! @ingroup archipelcore
    subclass of CPWindow that allows to add a TNStropheContact
*/
@implementation TNContactsController: CPObject
{
    @outlet CPButton        buttonAdd;
    @outlet CPButton        buttonCancel;
    @outlet CPPopover       mainPopover;
    @outlet CPTextField     newContactJID;
    @outlet CPTextField     newContactName;

    TNPubSubController      _pubsubController   @accessors(property=pubSubController);

    CPDictionary            _localAvatars;
}

#pragma mark -
#pragma mark Initialization

- (void)awakeFromCib
{
    _localAvatars = [CPDictionary dictionary];

    var bundle = [CPBundle mainBundle];

    [_localAvatars setObject:[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"Avatars/RemoteAvatars/defaultvm.png"]] forKey:@"vm"];
    [_localAvatars setObject:[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"Avatars/RemoteAvatars/defaulthypervisor.png"]] forKey:@"hypervisor"];

    [[CPNotificationCenter defaultCenter] addObserver:self selector:@selector(_performPushRosterAdded:) name:TNStropheRosterPushAddedContactNotification object:nil];
    [[CPNotificationCenter defaultCenter] addObserver:self selector:@selector(_performPushRosterRemoved:) name:TNStropheRosterPushRemovedContactNotification object:nil];
    [[CPNotificationCenter defaultCenter] addObserver:self selector:@selector(_performPushRosterUpdated:) name:TNStropheRosterPushUpdatedContactNotification object:nil];
    [[CPNotificationCenter defaultCenter] addObserver:self selector:@selector(_didRecieveContactVCard:) name:TNStropheContactVCardReceivedNotification object:nil];

    [newContactName setToolTip:CPLocalizedString(@"The display name of the new contact", @"The display name of the new contact")];
    [newContactJID setToolTip:CPLocalizedString(@"The XMPP JID of the contact", @"The XMPP JID of the contact")];
}

#pragma mark -
#pragma mark Utilities

- (void)subscribeToPubSubNodeOfContactWithJID:(TNStropheJID)aJID
{
    var roster = [[TNStropheIMClient defaultClient] roster];
    if ([roster analyseVCard:[[roster contactWithJID:aJID] vCard]] == TNArchipelEntityTypeUser)
        return;

    var nodeName = @"/archipel/" + [aJID bare] + @"/events",
        server = [TNStropheJID stropheJIDWithString:@"pubsub." + [aJID domain]];

    if (![_pubsubController nodeWithName:nodeName])
        [_pubsubController subscribeToNodeWithName:nodeName server:server];
}

- (void)unsubscribeToPubSubNodeOfContactWithJID:(TNStropheJID)aJID
{
    var roster = [[TNStropheIMClient defaultClient] roster];
    if ([roster analyseVCard:[[roster contactWithJID:aJID] vCard]] == TNArchipelEntityTypeUser)
        return;

    var nodeName = "/archipel/" + [aJID bare] + "/events",
        server = [TNStropheJID stropheJIDWithString:@"pubsub." + [aJID domain]];

    if ([_pubsubController nodeWithName:nodeName])
        [_pubsubController unsubscribeFromNodeWithName:nodeName server:server]
}

- (void)addContact
{
    var name = [newContactName stringValue],
        JID;

    try
    {
          JID = [TNStropheJID stropheJIDWithString:[newContactJID stringValue]]
    }
    catch (e)
    {
        JID = nil;
    }

    if (![JID node] || ![JID domain] || [JID resource])
    {
        [TNAlert showAlertWithMessage:CPLocalizedString(@"JID is not valid", @"JID is not valid")
                          informative:CPLocalizedString(@"You must enter a JID using the form user@domain.", @"You must enter a JID using the form user@domain.")
                                style:CPCriticalAlertStyle];
        return;
    }
    [[[TNStropheIMClient defaultClient] roster] addContact:JID withName:name inGroupWithPath:nil];

{'fraction_non_alphanumeric': 0.098374588335281, 'fraction_numerical': 0.0013810687347285669, 'mean_word_length': 4.616945107398568, 'pattern_counts': {'":': 0, '<': 27, '<?xml version=': 0, '>': 27, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2883824', 'n_tokens_mistral': 2973, 'n_tokens_neox': 2762, 'n_words': 717}