예제 #1
0
void ChatUrls::openChannelUrl(const QUrl &url)
{
  QStringList actions = ChatUrls::actions(url);
  if (actions.isEmpty())
    return;

  ClientChannel channel = ChatUrls::channel(url);
  if (!channel)
    return;

  QString action = actions.first();

  if (action == LS("open")) {
    ChatNotify::start(Notify::OpenChannel, channel->id());
  }
  else if (action == LS("info")) {
    ChatNotify::start(Notify::OpenInfo, channel->id());
  }
  else if (action == LS("insert")) {
    ChatNotify::start(Notify::InsertText, QChar(QChar::Nbsp) + QString(LS("<a class=\"nick color-%1\" href=\"%2\">%3</a>"))
        .arg(Gender::colorToString(channel->gender().color()))
        .arg(url.toString())
        .arg(Qt::escape(channel->name())) + QChar(QChar::Nbsp));
  }
  else if (action == LS("edit")) {
    if (actions.size() == 1)
      return;

    if (actions.at(1) == LS("topic") && channel->type() == SimpleID::ChannelId)
      ChatNotify::start(Notify::EditTopic, channel->id());
  }
}
예제 #2
0
ChannelTab::ChannelTab(ClientChannel channel, TabWidget *parent)
  : ChannelBaseTab(channel, LS("channel"), parent)
{
  m_userView = new UserView(channel, this);

  m_leftLayout = new QVBoxLayout(this);
  m_leftLayout->addWidget(m_chatView);
  m_leftLayout->setMargin(0);
  m_leftLayout->setSpacing(0);

  QWidget *left = new QWidget(this);
  left->setLayout(m_leftLayout);

  m_splitter = new QSplitter(this);
  m_splitter->addWidget(left);
  m_splitter->addWidget(m_userView);
  m_splitter->setStretchFactor(0, 1);
  m_splitter->setStretchFactor(1, 1);
  m_splitter->setOpaqueResize(false);

  QVBoxLayout *mainLay = new QVBoxLayout(this);
  mainLay->addWidget(m_splitter);
  mainLay->setMargin(0);
  mainLay->setSpacing(0);

  setText(channel->name());

  connect(ChatClient::channels(), SIGNAL(channels(QList<QByteArray>)), SLOT(channels(QList<QByteArray>)));
  connect(ChatClient::channels(), SIGNAL(joined(QByteArray,QByteArray)), SLOT(joined(QByteArray,QByteArray)));
  connect(ChatClient::channels(), SIGNAL(part(QByteArray,QByteArray)), SLOT(part(QByteArray,QByteArray)));
  connect(ChatClient::channels(), SIGNAL(quit(QByteArray,bool)), SLOT(quit(QByteArray,bool)));
  connect(ChatClient::channels(), SIGNAL(channel(QByteArray)), SLOT(channel(QByteArray)));

  m_chatView->add(ServiceMessage::joined(ChatClient::id()));
}
예제 #3
0
/*!
 * Отправка обновлённой информации о себе.
 */
ChannelPacket ChannelNotice::update(ClientChannel channel)
{
  ChannelPacket packet(new ChannelNotice(channel->id(), channel->id(), CHANNELS_UPDATE_CMD, DateTime::utc()));
  packet->setText(channel->name());
  packet->gender        = channel->gender().raw();
  packet->channelStatus = channel->status().value();
  return packet;
}
예제 #4
0
ChannelPacket ChannelNotice::info(ClientChannel channel, qint64 date)
{
  ChannelPacket packet(new ChannelNotice(channel->id(), channel->id(), CHANNELS_INFO_CMD, date ? date : DateTime::utc()));
  packet->setDirection(Server2Client);
  packet->setText(channel->name());
  packet->gender        = channel->gender().raw();
  packet->channelStatus = channel->status().value();
  return packet;
}
예제 #5
0
/*!
 * Создание или повторная инициализация вкладки канала.
 *
 * \param id     Идентификатор канала.
 * \param create \b true если необходимо создать канал.
 * \param show   \b true если необходимо выбрать эту вкладку.
 *
 * \return Возвращает указатель на вкладку или 0 в случае ошибки.
 */
ChannelBaseTab *TabWidget::channelTab(const QByteArray &id, bool create, bool show)
{
  SLOG_DEBUG("id =" << SimpleID::encode(id) << "create =" << create << "show =" << show);

  if (!Channel::isCompatibleId(id))
    return 0;

  ChannelBaseTab *tab = 0;

  if (m_channels.contains(id)) {
    tab = m_channels.value(id);
    create = false;
  }

  ClientChannel channel = ChatClient::channels()->get(id);
  if (!channel) {
    if (!m_prefetch.contains(id))
      m_prefetch.append(id);

    return 0;
  }

  if (create) {
    if (channel->type() == SimpleID::UserId)
      tab = new PrivateTab(channel, this);
    else if (channel->type() == SimpleID::ChannelId)
      tab = new ChannelTab(channel, this);

    if (tab) {
      m_channels[id] = tab;
      tab->setOnline();
      addTab(tab, tab->icon(), channel->name());
      connect(tab, SIGNAL(actionTriggered(bool)), SLOT(openTab()));

      if (channel->type() == SimpleID::ChannelId && isAutoPin(channel->id()))
        tab->pin();

      if (m_autoPin.contains(id)) {
        m_autoPin.removeAll(id);
        tab->pin();
        emit pinned(tab);
      }
    }

    closePage(PROGRESS_TAB);
    closePage(WELCOME_TAB);
  }

  if (show && tab)
    setCurrentIndex(indexOf(tab));

  return tab;
}
예제 #6
0
/*!
 * Формирование пакета для отправки клиенту заголовка канала.
 *
 * \param channel Канал.
 * \param dest    Идентификатор получателя.
 * \param command Команда.
 */
ChannelPacket ChannelNotice::channel(ClientChannel channel, const QByteArray &dest, const QString &command)
{
  ChannelPacket packet(new ChannelNotice(channel->id(), dest, command, DateTime::utc()));
  packet->setDirection(Server2Client);
  packet->setText(channel->name());
  packet->gender        = channel->gender().raw();
  packet->channelStatus = channel->status().value();
//  packet.setData(channel->feeds().headers(0));

  if (channel->type() == SimpleID::ChannelId)
    packet->channels = channel->channels().all();

  return packet;
}
예제 #7
0
PrivateTab::PrivateTab(ClientChannel channel, TabWidget *parent)
  : ChannelBaseTab(channel, LS("talk"), parent)
{
  QVBoxLayout *mainLay = new QVBoxLayout(this);
  mainLay->addWidget(m_chatView);
  mainLay->setMargin(0);
  mainLay->setSpacing(0);

  setText(channel->name());

  ChatClient::channels()->join(id());

  connect(ChatClient::channels(), SIGNAL(channel(ChannelInfo)), SLOT(channel(ChannelInfo)));
  connect(ChatClient::channels(), SIGNAL(quit(QByteArray)), SLOT(quit(QByteArray)));
  connect(ChatClient::i(), SIGNAL(online()), SLOT(online()));
}
예제 #8
0
bool FixUrlFilter::filter(QList<HtmlToken> &tokens, int options) const
{
  Q_UNUSED(options)

  QList<HtmlToken> out;
  QString name;
  bool remove = false;

  foreach (const HtmlToken &token, tokens) {
    if (token.type == HtmlToken::StartTag && token.tag == LS("a")) {
      HtmlATag tag(token);
      if (tag.url.startsWith(LS("chat://channel/"))) {
        ClientChannel user = ChatUrls::channel(QUrl(tag.url));
        if (user)
          name = user->name();
      }

      out.append(token);
    }
    else if (!name.isEmpty()) {
      if (name != token.text) {
        out.append(HtmlToken(name));
        out.append(HtmlToken(HtmlToken::Tag, LS("</a>")));
        remove = true;

        if (token.text.startsWith(name))
          out.append(HtmlToken(LC(' ') + token.text.mid(name.size())));
        else
          out.append(LC(' ') + token.text);
      }
      else
        out.append(token);

      name.clear();
    }
    else if (token.type == HtmlToken::EndTag && token.tag == LS("a") && remove) {
      remove = false;
    }
    else
      out.append(token);
  }

  tokens = out;
  return true;
}
예제 #9
0
/*!
 * Преобразует канал в URL адрес.
 *
 * \param channel Указатель на канал.
 * \param action  Действие над каналом.
 */
QUrl ChatUrls::toUrl(ClientChannel channel, const QString &action)
{
  QUrl out(LS("chat://channel"));
  out.setPath(SimpleID::encode(channel->id()) + (action.isEmpty() ? QString() : "/" + action));

  QList<QPair<QString, QString> > queries;
  queries.append(QPair<QString, QString>(LS("name"),   ChatId::toBase32(channel->name().toUtf8())));
  queries.append(QPair<QString, QString>(LS("gender"), QString::number(channel->gender().raw())));

# if QT_VERSION >= 0x050000
  QUrlQuery query;
  query.setQueryItems(queries);
  out.setQuery(query);
# else
  out.setQueryItems(queries);
# endif

  return out;
}
예제 #10
0
bool UrlFilter::filter(QList<HtmlToken> &tokens, int options) const
{
    Q_UNUSED(options)

    QString name;

    for (int i = 0; i < tokens.size(); ++i) {
        const HtmlToken &token = tokens.at(i);
        if (token.type == HtmlToken::StartTag && token.tag == LS("a")) {
            HtmlATag tag(tokens.at(i));

            if (tag.url.startsWith(LS("chat://channel/"))) {
                tag.classes = LS("nick");
                ClientChannel user = ChatUrls::channel(QUrl(tag.url));
                if (user) {
                    tag.classes += LC(' ') + SimpleID::encode(user->id());
                    name = user->name();

                    tag.classes += LS(" color-") + Gender::colorToString(user->gender().color());
                }

                tokens[i].text = tag.toText();
            }
            else if (tag.title.isEmpty()) {
                tag.title = tag.url;
                tokens[i].text = tag.toText();
            }
        }
        else if (token.type == HtmlToken::Text && !name.isEmpty()) {
            tokens[i].text = Qt::escape(name);
            name.clear();
        }
    }

    return true;
}
예제 #11
0
#include "feeds/FeedStorage.h"
#include "hooks/ClientFeedsImpl.h"
#include "net/packets/FeedNotice.h"
#include "net/SimpleID.h"
#include "sglobal.h"

ClientFeedsImpl::ClientFeedsImpl(QObject *parent)
  : Feeds(parent)
{
  ChatClient::feeds()->hooks()->add(this);
}


void ClientFeedsImpl::addImpl(ClientChannel channel, const ChannelInfo & /*info*/, const QVariantMap &json)
{
  SCHAT_DEBUG_STREAM("ClientFeedsImpl::addImpl()" << channel->name() << json.keys())

  if (json.isEmpty() || !json.contains(FEED_KEY_F))
    return;

  const QVariantMap data = json.value(FEED_KEY_F).toMap();
  if (data.isEmpty())
    return;

  QStringList feeds = unsynced(channel, data);
  feeds.removeAll(FEED_NAME_HOSTS);

  get(channel->id(), feeds);
}

bool
PingRequestHandler::processRequest(const YarpString &           request,
                                   const yarp::os::Bottle &     restOfInput,
                                   const YarpString &           senderChannel,
                                   yarp::os::ConnectionWriter * replyMechanism)
{
#if (! defined(ODL_ENABLE_LOGGING_))
# if MAC_OR_LINUX_
#  pragma unused(request,senderChannel)
# endif // MAC_OR_LINUX_
#endif // ! defined(ODL_ENABLE_LOGGING_)
    ODL_OBJENTER(); //####
    ODL_S3s("request = ", request, "restOfInput = ", restOfInput.toString(), //####
            "senderChannel = ", senderChannel); //####
    ODL_P1("replyMechanism = ", replyMechanism); //####
    bool result = true;

    try
    {
        // Validate the name as a channel name
        _response.clear();
        if (1 == restOfInput.size())
        {
            yarp::os::Value argument(restOfInput.get(0));

            if (argument.isString())
            {
                YarpString argAsString(argument.toString());

                if (Endpoint::CheckEndpointName(argAsString))
                {
                    RegistryService & theService = static_cast<RegistryService &>(_service);

                    theService.reportStatusChange(argAsString,
                                                  RegistryService::kRegistryPingFromService);
                    if (theService.checkForExistingService(argAsString))
                    {
                        // This service is already known, so just update the last-checked time.
                        theService.updateCheckedTimeForChannel(argAsString);
                    }
                    else if (theService.checkForExistingService(argAsString))
                    {
                        // Second try - something happened with the first call.
                        // This service is already known, so just update the last-checked time.
                        theService.updateCheckedTimeForChannel(argAsString);
                    }
                    else
                    {
                        // Send a 'name' request to the channel
                        YarpString      aName = GetRandomChannelName(HIDDEN_CHANNEL_PREFIX_
                                                                     BUILD_NAME_("ping_",
                                                                          DEFAULT_CHANNEL_ROOT_));
                        ClientChannel * outChannel = new ClientChannel;

                        if (outChannel)
                        {
                            if (outChannel->openWithRetries(aName, STANDARD_WAIT_TIME_))
                            {
                                if (outChannel->addOutputWithRetries(argAsString,
                                                                     STANDARD_WAIT_TIME_))
                                {
                                    yarp::os::Bottle message1(MpM_NAME_REQUEST_);
                                    yarp::os::Bottle reply;

                                    if (outChannel->writeBottle(message1, reply))
                                    {
                                        if (theService.processNameResponse(argAsString,
                                                                           ServiceResponse(reply)))
                                        {
                                            yarp::os::Bottle message2(MpM_LIST_REQUEST_);

                                            if (outChannel->writeBottle(message2, reply))
                                            {
                                                if (theService.processListResponse(argAsString,
                                                                           ServiceResponse(reply)))
                                                {
                                                    // Remember the response
                                                    _response.addString(MpM_OK_RESPONSE_);
                                                theService.updateCheckedTimeForChannel(argAsString);
                                                }
                                                else
                                                {
                                                    ODL_LOG("! (theService.processList" //####
                                                            "Response(argAsString, reply))"); //####
                                                    _response.addString(MpM_FAILED_RESPONSE_);
                                                    _response.addString("Invalid response to "
                                                                        "'list' request");
                                                }
                                            }
                                            else
                                            {
                                                ODL_LOG("! (outChannel->" //####
                                                        "writeBottle(message2, reply))"); //####
                                                _response.addString(MpM_FAILED_RESPONSE_);
                                                _response.addString("Could not write to channel");
#if defined(MpM_StallOnSendProblem)
                                                Stall();
#endif // defined(MpM_StallOnSendProblem)
                                            }
                                        }
                                        else
                                        {
                                            ODL_LOG("! (theService.processNameResponse(" //####
                                                    "argAsString, reply))"); //####
                                            _response.addString(MpM_FAILED_RESPONSE_);
                                            _response.addString("Invalid response to 'name' "
                                                                "request");
                                        }
                                    }
                                    else
                                    {
                                        ODL_LOG("! (outChannel->writeBottle(message1, " //####
                                                "reply))"); //####
                                        _response.addString(MpM_FAILED_RESPONSE_);
                                        _response.addString("Could not write to channel");
#if defined(MpM_StallOnSendProblem)
                                        Stall();
#endif // defined(MpM_StallOnSendProblem)
                                    }
#if defined(MpM_DoExplicitDisconnect)
                                if (! Utilities::NetworkDisconnectWithRetries(outChannel->name(),
                                                                              argAsString,
                                                                              STANDARD_WAIT_TIME_))
                                    {
                                        ODL_LOG("(! Utilities::NetworkDisconnectWith" //####
                                                "Retries(outChannel->name(), " //####
                                                "argAsString, STANDARD_WAIT_TIME_))"); //####
                                    }
#endif // defined(MpM_DoExplicitDisconnect)
                                }
                                else
                                {
                                    ODL_LOG("! (outChannel->addOutputWithRetries(" //####
                                            "argAsString, STANDARD_WAIT_TIME_))"); //####
                                    _response.addString(MpM_FAILED_RESPONSE_);
                                    _response.addString("Could not connect to channel");
                                    _response.addString(argAsString);
                                }
#if defined(MpM_DoExplicitClose)
                                outChannel->close();
#endif // defined(MpM_DoExplicitClose)
                            }
                            else
                            {
                                ODL_LOG("! (outChannel->openWithRetries(aName, " //####
                                        "STANDARD_WAIT_TIME_))"); //####
                                _response.addString(MpM_FAILED_RESPONSE_);
                                _response.addString("Channel could not be opened");
                            }
                            BaseChannel::RelinquishChannel(outChannel);
                        }
                        else
                        {
                            ODL_LOG("! (outChannel)");
                        }
                    }
                }
                else
                {
                    ODL_LOG("! (Endpoint::CheckEndpointName(argAsString))"); //####
                    _response.addString(MpM_FAILED_RESPONSE_);
                    _response.addString("Invalid channel name");
                }
            }
            else
            {
                ODL_LOG("! (argument.isString())"); //####
                _response.addString(MpM_FAILED_RESPONSE_);
                _response.addString("Invalid channel name");
            }
        }
        else
        {
            ODL_LOG("! (1 == restOfInput.size())"); //####
            _response.addString(MpM_FAILED_RESPONSE_);
            _response.addString("Missing channel name or extra arguments to request");
        }
        sendResponse(replyMechanism);
    }
    catch (...)
    {
        ODL_LOG("Exception caught"); //####
        throw;
    }
    ODL_OBJEXIT_B(result); //####
    return result;
} // PingRequestHandler::processRequest