Exemplo n.º 1
0
/* troche brzydkiego kodu ;) częsciowo skopiowanego z modułu history-migration*/
void ImportFromGG::run()
{
  //kodowanie historii
  QTextCodec::setCodecForCStrings(QTextCodec::codecForName("cp1250"));

  if (cancel)
    return;

  /* przesuń się na index */
  arch->seek(gg_header.index_off);

  /* oblicz ilość sekcji w indeksie */
  int index_entries=gg_header.index_size/sizeof(gg_index);

  /* odczytaj kolejne sekcje */
  for (int i=0;i<index_entries;i++)
  {
    arch->read(reinterpret_cast<char*>(&gg_index), sizeof(gg_index));
    if (i!=1) 
      continue;         //pierwsza sekcja (0) zawiera smieci, druga(1) wiadomosci, inne nas nie interesują
    /* zapamiętaj pozycje w pliku, bo zaraz bedziemy po nim jeździć */
    qint64 pos=arch->pos();

    /* offset bloku danych liczony względem sekcji danych (data_off w strukturze nagłówka) */
    /* przesuń się na pierwszy blok */
    arch->seek(gg_header.data_off + gg_index.first_block_off);
    emit boundaries(gg_index.first_block_off,gg_index.last_block_off);     //ustaw progress bar

    /* analizuj kolejne bloki */
    do
    {
      arch->read(reinterpret_cast<char*>(&gg_block), sizeof(gg_block));          //wczytaj nagłówek bloku

      /* odczytaj wszystkie nagłówki wiadomości znajdujące się za nagłówkiem */
      int msg_entries=gg_block.block_size/sizeof(struct msg_header);  //liczba wiadomości
      gg_msg_header=new struct msg_header[msg_entries];

      arch->read(reinterpret_cast<char*>(gg_msg_header), sizeof(struct msg_header) *msg_entries);
      for (int j=0;j<msg_entries;j++)
      {
        arch->seek(gg_header.data_off + gg_msg_header[j].msg_off);
        /* odczytaj nagłówek wiadomości */
        arch->read(reinterpret_cast<char*>(&gg_message), sizeof(gg_message));

        Message message=Message::create();

        /* na podstawie message.recivers rozsądź czy wiadomość przychodząca czy wychodząca */
        /* jeśli message.recivers==0 to wiadomość przychodząca */
        /* jeśli message.recivers>0 i uin inny niż w nagłówku to przychodząca konferencja */
        /* jeśli message.recivers>0 i uin jak w nagłówku to wychodząca (może również to być konferencja) */
        if (gg_message.recivers==0)   //przychodząca
        {
          /* doczytaj ciąg dalszy wiadomości */
          arch->read(reinterpret_cast<char*>(&gg_rcv_msg), sizeof(gg_rcv_msg));
          /* odczytaj treść wiadomości */
          QByteArray msg=arch->read(gg_rcv_msg.len);

          int uin = gg_message.sender_uin;
          UinsList uinsList;
          uinsList << uin;
          Chat chat=chatFromUinsList(uinsList);

          Contact user=ContactManager::instance()->byId(account, QString::number(uin), ActionCreateAndAdd);
          message.setMessageChat(chat);
          message.setMessageSender(user);
          message.setContent(decode(msg, user));
          message.setSendDate(QDateTime::fromTime_t (gg_message.send_time));
          message.setReceiveDate(QDateTime::fromTime_t (gg_rcv_msg.rcv_time));
          message.setType(MessageTypeReceived);

          History::instance()->currentStorage()->appendMessage(message);
          //1.  argument (osoba/by z którymi gadamy) 2. ten kto pisał czyli w tym wypadku dwa razy to samo
          //History::instance()->currentStorage()->appendMessage(uins, gg_message.sender_uin, decode ( msg,uins[0] ),false,gg_message.send_time,true,gg_rcv_msg.rcv_time );
        }
        else                    //wychodząca (konferencja) lub przychodząca konferencja
        {
          /* w pliku kolejno:
              0x0C            [n] * 4 bajty  numerki odbiorców
              0x0C + [n] * 4  4 bajty  prawdopodobnie czas dostarczenia wiadomości do odbiorcy
              0x10 + [n] * 4  4 bajty  długość wiadomości (len)
              0x14 + [n] * 4  [len] bajtów  wiadomość
          */
          quint32* us= new quint32[gg_message.recivers];
          quint32 time;
          quint32 len;

          arch->read(reinterpret_cast<char*>(us), sizeof(quint32) *gg_message.recivers);
          arch->read(reinterpret_cast<char*>(&time), sizeof(quint32));
          arch->read(reinterpret_cast<char*>(&len), sizeof(quint32));

          /* odczytaj treść wiadomości */
          QByteArray msg=arch->read(len);
          UinsList uins;
          bool outgoing= owner_uin==gg_message.sender_uin;
          if (outgoing==false)                  //konferencja lub wiadomość przychodząca
            uins << gg_message.sender_uin;      //dopisz tego co przysyła też do listy odbiorców

          for (int k=0; k<gg_message.recivers; k++)
            if (us[k]!=owner_uin)
              uins << us[k];    //stare gg (chyba <6.0) traktuje zwykle rozmowy jak konferencje dodając osobe wysylającą (własciciela) do listy odbiorców, wyrzuć go

          Contact user=outgoing? account.accountContact()
                                 :ContactManager::instance()->byId(account, QString::number(gg_message.sender_uin), ActionCreateAndAdd);
          message.setMessageChat(chatFromUinsList(uins));
          message.setMessageSender(user);
          message.setContent(decode(msg, user));
//           message.setContent(decode(msg, uins[0]));   //1. uin ? nie pamięta skąd to sie wzięło, widocznie tak jest ;)

          message.setSendDate(QDateTime::fromTime_t (gg_message.send_time));
          message.setReceiveDate(QDateTime::fromTime_t (gg_rcv_msg.rcv_time));
          message.setType(outgoing ? MessageTypeSent : MessageTypeReceived);

          History::instance()->currentStorage()->appendMessage(message);
        }
      }
      /* przesuń się do kolejnego bloku */
      delete [] gg_msg_header;
      if (gg_block.next_block!=0)
        arch->seek(gg_header.data_off + gg_block.next_block);
      position=gg_block.next_block;
    }
    while (gg_block.next_block!=0 && !cancel);   //pracuj dopóki cancel==false
    /* powrót do sekcji */
    arch->seek(pos);
  }

  arch->close();
  return;
}
Exemplo n.º 2
0
void HistoryImportThread::run()
{
	// we have to use this guard as a parent for HistoryImporterChatData
	// without this there is a backtrace:
	// "Warning: QObject: Cannot create children for a parent that is in a different thread."
	// and Kadu is crashing as in http://kadu.net/mantis/view.php?id=1938
	QObject *guard = new QObject();

	History::instance()->setSyncEnabled(false);

	ImportedEntries = 0;

	foreach (const UinsList &uinsList, UinsLists)
	{
		if (Canceled)
			break;

		ImportedChats++;

		Chat chat = chatFromUinsList(uinsList);
		// we cannot import into non-existing chat
		// this means chat with ourself on the list
		if (!chat || !chat.data())
			continue;

		QList<HistoryEntry> entries = HistoryMigrationHelper::historyEntries(Path, uinsList);

		// guard as a parent. See above
		HistoryImporterChatData *historyImporterChatData = chat.data()->moduleStorableData<HistoryImporterChatData>("history-importer", guard, true);
		if (historyImporterChatData->imported())
		{
			ImportedEntries += entries.count();
			continue;
		}

		ImportedMessages = 0;
		TotalMessages = entries.count();

		if (Canceled)
			break;

		foreach (const HistoryEntry &entry, entries)
		{
			if (Canceled && CancelForced)
				break;
			importEntry(chat, entry);
			ImportedMessages++;
		}

		if (Canceled && CancelForced)
			break;

		historyImporterChatData->setImported(true);
		historyImporterChatData->store();
		// force sync for every chat
		History::instance()->forceSync();
	}

	// delete guard, so HistoryImporterChatData is properly destroyed
	delete guard;

	History::instance()->setSyncEnabled(true);
}