Beispiel #1
0
/*!
 * Получение канала из URL адреса.
 */
ClientChannel ChatUrls::channel(const QUrl &url)
{
  ClientChannel channel;
  if (url.scheme() != LS("chat") && url.host() != LS("channel"))
    return channel;

  QStringList path = ChatUrls::path(url);
  if (path.isEmpty())
    return channel;

  QByteArray id = SimpleID::decode(path.at(0).toLatin1());
  if (!Channel::isCompatibleId(id))
    return channel;

  channel = ChatClient::channels()->get(id);
  if (channel)
    return channel;

  channel = ClientChannel(new Channel(id, ChatId::fromBase32(QUrlQuery(url).queryItemValue(LS("name")).toLatin1())));
  channel->gender().setRaw(QUrlQuery(url).queryItemValue(LS("gender")).toInt());
  if (!channel->isValid())
    return ClientChannel();

  return channel;
}
Beispiel #2
0
/*!
 * Получение заголовков локальных фидов.
 */
void RawFeedsCmd::localFeeds(const QByteArray &dest)
{
  if (!m_plugin->isEnabled())
    return;

  if (!TabWidget::i())
    return;

  ClientChannel channel = ChatClient::channels()->get(dest);
  if (!channel)
    return;

  QVariantMap json;

  QMapIterator<QString, FeedPtr> i(channel->feeds().all());
  while (i.hasNext()) {
    i.next();
    Feed::merge(i.key(), json, i.value()->head().save());
  }

  if (json.isEmpty())
    return;

  RawFeedsMessage message(dest, LS("headers"), Feed::merge(LS("feeds"), json));
  TabWidget::add(message, false);
}
Beispiel #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;
}
Beispiel #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;
}
Beispiel #5
0
/*!
 * Сообщение о выходе пользователя из чата.
 */
ServiceMessage ServiceMessage::quit(const QByteArray &user)
{
  QString text;
  ClientChannel channel = ChatClient::channels()->get(user);

  if (channel) {
    if (channel->gender().value() == Gender::Female)
      text = tr("has quit chat", "Female");
    else
      text = tr("has quit chat", "Male");
  }

  return ServiceMessage(text, user);
}
Beispiel #6
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()));
}
Beispiel #7
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;
}
Beispiel #8
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());
  }
}
Beispiel #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;
}
Beispiel #10
0
UserItem::UserItem(ClientChannel user, ClientChannel channel)
  : QStandardItem()
  , m_bold(false)
  , m_italic(false)
  , m_self(false)
  , m_underline(false)
  , m_channel(channel)
  , m_user(user)
{
  m_self = ChatClient::id() == user->id();

  reload();
}
Beispiel #11
0
void ChatView::contextMenu(QMenu *menu, const QWebHitTestResult &result)
{
  menu->addSeparator();

  const QUrl url = result.linkUrl();
  if (url.scheme() == LS("chat") && url.host() == LS("channel"))
    Hooks::ChannelMenu::bind(menu, ChatUrls::channel(url), Hooks::ChatViewScope);
  else
    Hooks::ChannelMenu::bind(menu, ChatClient::channels()->get(m_id), Hooks::ChatViewScope);

  menu->addSeparator();
  QMenu *display = menu->addMenu(SCHAT_ICON(Gear), tr("Display"));
  display->addAction(m_seconds);
  display->addAction(m_service);
  developerMenu(display);
  display->removeAction(pageAction(QWebPage::Reload));

  menu->addAction(m_autoscroll);
  menu->addSeparator();

  ClientChannel channel = ChatClient::channels()->get(id());
  if (channel && channel->data().value(LS("page")) == 1)
    menu->addAction(m_reload);
  else
    menu->addAction(m_clear);

  if (!result.isContentEditable()) {
    menu->removeAction(pageAction(QWebPage::SelectAll));
    menu->addAction(pageAction(QWebPage::SelectAll));
  }

  menu->removeAction(pageAction(QWebPage::Reload));
  menu->removeAction(pageAction(QWebPage::InspectElement));

  connect(menu, SIGNAL(triggered(QAction*)), SLOT(menuTriggered(QAction*)));

  ChatViewHooks::contextMenu(this, menu, result);
}
Beispiel #12
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;
}
Beispiel #13
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()));
}
Beispiel #14
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;
}
Beispiel #15
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;
}
Beispiel #16
0
/*!
 * Иконка канала.
 */
QIcon ChatIcons::icon(ClientChannel channel, int options)
{
  QString file = LS(":/images/channel.png");

  if (channel->type() == ChatId::UserId || channel->id().isEmpty()) {
    file = LS(":/images/user");
    int gender = channel->gender().value();
    int color  = channel->gender().color();

    if (gender == Gender::Unknown) {
      file += LS("-unknown");
    }
    else if (gender == Gender::Ghost) {
      file += LS("-ghost");
    }
    else if (gender == Gender::Bot) {
      file += LS("-bot");
    }
    else if (color != Gender::Default) {
      file += LS("-") + Gender::colorToString(color);
    }

    if (gender == Gender::Female)
      file += LS("-female");

    file += LS(".png");
  }
  else if (channel->type() == ChatId::ChannelId && channel->gender().color() == Gender::Green) {
    file = LS(":/images/secure.png");
  }

  const Status& status = channel->status();
  if (options & OfflineStatus && status.value() == Status::Offline && !(options & Statuses))
    options |= Statuses;

  if (options & Statuses) {
    if (options & OfflineStatus && (status.value() == Status::Offline || !channel->isSynced()))
      return QIcon(QIcon(file).pixmap(16, 16, QIcon::Disabled));

    return ChatIcons::icon(file, overlay(status.value()));
  }

  return QIcon(file);
}
Beispiel #17
0
/*!
 * Получение идентификатора пользователя из менеджера сетей
 * и установка базовых данных из настроек.
 */
QByteArray Networks::id() const
{
  ClientChannel channel = ChatClient::channel();
  channel->setName(ChatCore::settings()->value("Profile/Nick").toString());
  channel->gender().setRaw(ChatCore::settings()->value("Profile/Gender").toInt());
  channel->status().set(ChatCore::settings()->value("Profile/Status").toInt());

  Network item = ChatCore::networks()->item(ChatCore::networks()->selected());
  if (!item->isValid())
    return QByteArray();

  channel->setId(item->userId());

  return channel->id();
}
Beispiel #18
0
#include "client/ClientFeeds.h"
#include "debugstream.h"
#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