From 93d3575dff1db593b516821478510a4fecf0649e Mon Sep 17 00:00:00 2001 From: mataes2007 Date: Sat, 26 Nov 2011 12:28:23 +0000 Subject: added ImportTrillian git-svn-id: http://miranda-plugins.googlecode.com/svn/trunk@211 e753b5eb-9565-29b2-b5c5-2cc6f99dfbcb --- ImportTrillian/docs/InstallScript.xml | 27 + ImportTrillian/docs/importTrillian.png | Bin 0 -> 8040 bytes ImportTrillian/docs/importTrillian_license.txt | 340 +++++++++ ImportTrillian/docs/importTrillian_readme.txt | 112 +++ ImportTrillian/docs/importTrillian_translate.txt | 43 ++ ImportTrillian/import.ico | Bin 0 -> 3638 bytes ImportTrillian/main.c | 925 +++++++++++++++++++++++ ImportTrillian/resource.h | 69 ++ ImportTrillian/resource.rc | 247 ++++++ 9 files changed, 1763 insertions(+) create mode 100644 ImportTrillian/docs/InstallScript.xml create mode 100644 ImportTrillian/docs/importTrillian.png create mode 100644 ImportTrillian/docs/importTrillian_license.txt create mode 100644 ImportTrillian/docs/importTrillian_readme.txt create mode 100644 ImportTrillian/docs/importTrillian_translate.txt create mode 100644 ImportTrillian/import.ico create mode 100644 ImportTrillian/main.c create mode 100644 ImportTrillian/resource.h create mode 100644 ImportTrillian/resource.rc diff --git a/ImportTrillian/docs/InstallScript.xml b/ImportTrillian/docs/InstallScript.xml new file mode 100644 index 0000000..5b762dc --- /dev/null +++ b/ImportTrillian/docs/InstallScript.xml @@ -0,0 +1,27 @@ + + + + Trillian history/contact import plugin + Daniel 'Spin' Hofer + 0.2.0.0 + plugin + + + + Plugin File + importTrillian.dll + + + + Readme, translate and license files + importTrillian_readme.txt + importTrillian_translate.txt + importTrillian_license.txt + + + + + importTrillian_readme.txt + + + diff --git a/ImportTrillian/docs/importTrillian.png b/ImportTrillian/docs/importTrillian.png new file mode 100644 index 0000000..3b7b12e Binary files /dev/null and b/ImportTrillian/docs/importTrillian.png differ diff --git a/ImportTrillian/docs/importTrillian_license.txt b/ImportTrillian/docs/importTrillian_license.txt new file mode 100644 index 0000000..5b6e7c6 --- /dev/null +++ b/ImportTrillian/docs/importTrillian_license.txt @@ -0,0 +1,340 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + 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 2 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, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/ImportTrillian/docs/importTrillian_readme.txt b/ImportTrillian/docs/importTrillian_readme.txt new file mode 100644 index 0000000..d3fcc02 --- /dev/null +++ b/ImportTrillian/docs/importTrillian_readme.txt @@ -0,0 +1,112 @@ +Trillian message history and contacts importer +---------------------------------------------- +Imports message histories and contacts from Trillian instant messenger. +Features: +- Support for ICQ, MSN, AIM, Yahoo! and IRC protocols +- Succesfully tested on various systems and Trillian log formats +- New protocols can easily be added, just send me part of a log file +- Lots of options for importing and yet: +- Easy to use +- UTF8 support (and detection) + +I included the source code so if you improve the Plugin please let me know: +dhofer(at)freesurf(dot)ch + +Installation +------------ +Copy the "importTrillian.dll" into your miranda\plugins directory. You can then import +the history using the main menu entry. + +Importing history +----------------- +Select the menu entry "Import Trillian history/contacts..." in the main Menu. Then chose +which protocols should be imported and click "Start". This will only import the history +of existing contacts. +It's highly recommended to deactivate any notification plugin/setting before importing +the history! + +Importing contacts +------------------ +Same as importing history but you have to select the "Add new contacts from history" +option. If you imported the history of your existing contacts before you should +deselect the "Import history of existing contacts" to avoid duplicate entires. +This will ignore contacts with empty chat logs. + +ATTENTION +--------- +This plugin works for my Trillian logs but it might import bogus data with your logs. +It also doesn't check for dublicate messages so you'll have to let it complete the import. +I'm not responsible for any damage caused by this plugin, use it at your own risk! +(I recommend backing up the Miranda database before using it.) +The import can take a long time (~1h for me). + +If you encounter a crash or a false import please send me the part of the Trillian .log +file that isn't imported correctly and I'll try to fix it. + +Changelog +--------- + +0.2.0 +----- +- Fixed some UTF8 importing issues +- Added user options for log file format +- Added the option to delete events prior to a specified date +- Fixed a timestamp detection bug +- Improved duplicate event handling + +0.1.8 +----- +- Fixed folder selection issue + +0.1.7 +----- +- Added fast mode + +0.1.6 +----- +- Added option to skip duplicate events +- Improved Trillian v3.1 support +- Fixed crash bug +- Fixed name length + +0.1.4 +----- +- Added experimental Trillian v3.1 support +- Fixed wrong message ordering +- Fixed whitespace before sent messages +- Fixed first log file not being imported +- Fixed crash bug on some rare occasions + +0.1.2 +----- +- Added translation support +- Speed improvement +- Recoded some functions +- Added GPL headers & licence + +0.1.0 +----- +- Added support for Yahoo! message history importing +- Added support for IRC message history importing +- Added contact importing +- Added new options +- Fixed a memory leak + +0.0.4 +------ +- Added support for AIM message history importing +- Added importing of status report messages +- Fixed import bug for messages with [h:m:s] time format + +0.0.2 +------ +- Added support for MSN message history importing +- Improved dialogs + +0.0.1b +------ +- Recompiled using proper flags + +0.0.1 +----- +- Initial public release \ No newline at end of file diff --git a/ImportTrillian/docs/importTrillian_translate.txt b/ImportTrillian/docs/importTrillian_translate.txt new file mode 100644 index 0000000..c1b99a6 --- /dev/null +++ b/ImportTrillian/docs/importTrillian_translate.txt @@ -0,0 +1,43 @@ +;Settins dialog +[Import settings] +[Trillian logs directory] +[Protocols] +[Contacts] +[Import] +[Browse] +[Start] +[Cancel] +[Import ICQ history] +[Import MSN history] +[Import AIM history] +[Import Yahoo! history] +[Import IRC history] +[Import IRC channel history] +[Import history of existing contacts] +[Add new contacts if a contact from the history is not on the list] +[Skip duplicate messages] +[Import messages] +[Import status reports (filetransfers, away msg, etc.)] +[Fast mode (backup your db!)] +[There's nothing to import, please\nselect a protocol.] +[Invalid settings] +;Progress dialog +[Importing History] +[Import in progress...] +[Overall (current protocol)] +[File] +[OK] +[WARNING: If you cancel now and continue later you might\nget duplicate entries. Cancel anyways?] +[Please select the \'logs\' folder in your Trillian directory] +[Warning] +[line] +[No logs found for this protocol.] +[Done importing %d contact history files!] +[\nCheck your UIN and path settings. Path musst end with \\logs] +[Import Trillian history/contacts...] +[UTF8] +[Replace duplicate messages] +[Delete entries before] +[(Must match this format exactly: MMM DD HH:mm:ss YYYY)] +[Try to auto-detect UTF8 strings (is slow, detects öäüßéàèç)] +[Interpret logs as UTF8 files] \ No newline at end of file diff --git a/ImportTrillian/import.ico b/ImportTrillian/import.ico new file mode 100644 index 0000000..b7c7753 Binary files /dev/null and b/ImportTrillian/import.ico differ diff --git a/ImportTrillian/main.c b/ImportTrillian/main.c new file mode 100644 index 0000000..05a0724 --- /dev/null +++ b/ImportTrillian/main.c @@ -0,0 +1,925 @@ +/* + importTrillian: History & Contacts import plugin for Miranda-IM. + Copyright (C) 2005 Daniel 'Spin' Hofer + + 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 2 + 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, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ +#include +#include +#include +#include +#include +#include +#include "resource.h" +#include "newpluginapi.h" +#include "m_langpack.h" +#include "m_system.h" +#include "m_database.h" +#include "m_clist.h" +#include "m_protomod.h" + +#pragma warning( disable: 4311 ) +#pragma warning( disable: 4312 ) + +#define IMPORT_MODULE "MIMImportTrillian" +#define IMPORT_SERVICE "MIMImportTrillian/ImportTrillian" +#define DLG_UPDATE 0x2000 + +#define SESS_START1 "Session Start (" +#define SESS_START2 "Start (ICQ - " +#define SESS_START3 "Start (MSN - " +#define SESS_START4 "Start (AIM - " +#define SESS_START5 "Start (Yahoo! - " +#define SESS_START6 "Start (IRC - " +#define SESS_STOP "Session Close (" + +void Utf8ToAnsi(const char *szIn, char *szOut, int cchOut); + +static int ImportCommand( WPARAM wParam,LPARAM lParam ); +static int ImportMessages( ); +static char line[2048]; +static char file[MAX_PATH]; +static char delBeforeDate[MAX_PATH]; +static char icqUin[32]; + +time_t delBeforeTS; +static HANDLE hHookModulesLoaded; +HINSTANCE hInst; +PLUGINLINK *pluginLink; +char status[256]; +BOOL importProt[5] = { 1, 1, 1, 1, 1 }; +BOOL importNic = TRUE; +BOOL importCha = TRUE; +BOOL importMsg = TRUE; +BOOL importStat = TRUE; +BOOL importAdd = FALSE; +BOOL importEx = TRUE; +BOOL skipDup = FALSE; +BOOL repDup = TRUE; +BOOL delBefore = FALSE; +BOOL speedMode = TRUE; +BOOL utf8AutoDetect = FALSE; +BOOL utf8DoAlways = FALSE; +int aborting = 0; +int finished = 0; + +int getNick = 0; +char lastNick[256]; + +PLUGININFO pluginInfo = { + sizeof(PLUGININFO), + "Import Trillian history/contacts", + PLUGIN_MAKE_VERSION(0,2,0,0), + "Miranda IM history/contact import plugin.", + "Daniel \'Zpin\' Hofer", + "dhofer@freesurf.ch", + "©2006 by Daniel \'Zpin\' Hofer", + "http://www.zpin.ch", + 0, + 0 +}; + + +BOOL WINAPI DllMain( HINSTANCE hinstDLL,DWORD fdwReason,LPVOID lpvReserved ) +{ + hInst = hinstDLL; + return TRUE; +} + +static int readLine( FILE *f ) +{ + int i = 0; + char chr; + chr = fgetc( f ); + while( chr != '\n' && !feof( f ) && i < 2047 ) + { + line[i++] = chr; + chr = fgetc( f ); + } + line[i] = '\0'; + return !feof( f ); +} + +struct tm string2Tm( char *string ) +{ + char mon[4]; + int mt = 0, day, hr, min, sec, yr; + struct tm starttime; + + sscanf( string, "%3s %d %d:%d:%d %d", &mon, &day, &hr, &min, &sec, &yr ); + if( !strcmp( mon, "Jan" ) ) + mt = 0; + else if( !strcmp( mon, "Feb" ) ) + mt = 1; + else if( !strcmp( mon, "Mar" ) ) + mt = 2; + else if( !strcmp( mon, "Apr" ) ) + mt = 3; + else if( !strcmp( mon, "May" ) ) + mt = 4; + else if( !strcmp( mon, "Jun" ) ) + mt = 5; + else if( !strcmp( mon, "Jul" ) ) + mt = 6; + else if( !strcmp( mon, "Aug" ) ) + mt = 7; + else if( !strcmp( mon, "Sep" ) ) + mt = 8; + else if( !strcmp( mon, "Oct" ) ) + mt = 9; + else if( !strcmp( mon, "Nov" ) ) + mt = 10; + else if( !strcmp( mon, "Dec" ) ) + mt = 11; + + starttime.tm_mon = mt; + starttime.tm_mday = day; + starttime.tm_hour = hr; + starttime.tm_min = min; + starttime.tm_sec = sec; + starttime.tm_year = yr - 1900; + return starttime; +} + +BOOL CALLBACK StartupDialogProc( HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam ) +{ + FILE *fl; + switch( message ) + { + case WM_INITDIALOG: + SetWindowText( hdlg, Translate( "Import settings" ) ); + + SetDlgItemText( hdlg, IDC_INFO1, Translate( "Trillian logs directory" ) ); + SetDlgItemText( hdlg, IDC_INFO2, Translate( "Protocols" ) ); + SetDlgItemText( hdlg, IDC_INFO3, Translate( "Contacts" ) ); + SetDlgItemText( hdlg, IDC_INFO4, Translate( "Import" ) ); + SetDlgItemText( hdlg, IDC_BROWSE, Translate( "Browse" ) ); + SetDlgItemText( hdlg, IDC_UTF8, Translate( "UTF8" ) ); + + SetDlgItemText( hdlg, IDOK, Translate( "Start" ) ); + SetDlgItemText( hdlg, IDCANCEL, Translate( "Cancel" ) ); + + SetDlgItemText( hdlg, IDC_IMPICQ, Translate( "Import ICQ history" ) ); + SetDlgItemText( hdlg, IDC_IMPMSN, Translate( "Import MSN history" ) ); + SetDlgItemText( hdlg, IDC_IMPAIM, Translate( "Import AIM history" ) ); + SetDlgItemText( hdlg, IDC_IMPICQ, Translate( "Import ICQ history" ) ); + SetDlgItemText( hdlg, IDC_IMPYAHOO, Translate( "Import Yahoo! history" ) ); + SetDlgItemText( hdlg, IDC_IMPIRC, Translate( "Import IRC history" ) ); + SetDlgItemText( hdlg, IDC_IMPCHA, Translate( "Import IRC channel history" ) ); + + SetDlgItemText( hdlg, IDC_IMPEX, Translate( "Import history of existing contacts" ) ); + SetDlgItemText( hdlg, IDC_IMPADD, Translate( "Add new contacts if a contact from the history is not on the list" ) ); + SetDlgItemText( hdlg, IDC_IMPMSG, Translate( "Import messages" ) ); + SetDlgItemText( hdlg, IDC_SKIPDUP, Translate( "Skip duplicate messages" ) ); + SetDlgItemText( hdlg, IDC_REPDUP, Translate( "Replace duplicate messages" ) ); + SetDlgItemText( hdlg, IDC_DELBEF, Translate( "Delete entries before" ) ); + SetDlgItemText( hdlg, IDC_DELBEFINFO, Translate( "(Must match this format exactly: MMM DD HH:mm:ss YYYY)" ) ); + SetDlgItemText( hdlg, IDC_IMPSTAT, Translate( "Import status reports (filetransfers, away msg, etc.)" ) ); + SetDlgItemText( hdlg, IDC_SPEEDMODE, Translate( "Fast mode (backup your db!)" ) ); + SetDlgItemText( hdlg, IDC_UTF8AUTO, Translate( "Try to auto-detect UTF8 strings (is slow, detects öäüßéàèç)" ) ); + SetDlgItemText( hdlg, IDC_UTF8ALWAYS, Translate( "Interpret logs as UTF8 files" ) ); + + + ShowWindow( hdlg, SW_SHOW ); + SendMessage( hdlg, WM_SETICON, ICON_BIG, (LPARAM)LoadIcon(hInst,MAKEINTRESOURCE(IDI_IMPORT))); + fl = fopen( "importTrillian.ini", "r" ); + if( fl ) + { + int i = -1; + do + { + i++; + file[i] = fgetc( fl ); + } while( file[i] != EOF && file[i] != '\n' && i < MAX_PATH ); + file[i] = '\0'; + fclose( fl ); + } + + SendDlgItemMessage( hdlg, IDC_LOGDIR, WM_SETTEXT, 0, (DWORD)file ); + SendDlgItemMessage( hdlg, IDC_DELBEFDATE, WM_SETTEXT, 0, (DWORD)"Mar 16 20:31:29 2005" ); + CheckDlgButton( hdlg, IDC_IMPICQ, TRUE ); + CheckDlgButton( hdlg, IDC_IMPMSN, TRUE ); + CheckDlgButton( hdlg, IDC_IMPAIM, TRUE ); + CheckDlgButton( hdlg, IDC_IMPYAHOO, TRUE ); + CheckDlgButton( hdlg, IDC_IMPIRC, TRUE ); + CheckDlgButton( hdlg, IDC_IMPCHA, TRUE ); + CheckDlgButton( hdlg, IDC_IMPMSG, TRUE ); + CheckDlgButton( hdlg, IDC_IMPSTAT, TRUE ); + CheckDlgButton( hdlg, IDC_IMPEX, TRUE ); + CheckDlgButton( hdlg, IDC_REPDUP, TRUE ); + CheckDlgButton( hdlg, IDC_SPEEDMODE, TRUE ); + return TRUE; + case WM_COMMAND: + switch( LOWORD( wParam ) ) + { + case IDC_BROWSE: + { + BROWSEINFO bi = { 0 }; + LPITEMIDLIST pidl = SHBrowseForFolder( &bi ); + bi.lpszTitle = Translate( "Please select the \'logs\' folder in your Trillian directory" ); + if( pidl != 0 ) + SHGetPathFromIDList ( pidl, file ); + SendDlgItemMessage( hdlg, IDC_LOGDIR, WM_SETTEXT, 0, (DWORD)file ); + } + break; + case IDOK: + { + struct tm time; + importProt[0] = IsDlgButtonChecked( hdlg, IDC_IMPICQ ); + importProt[1] = IsDlgButtonChecked( hdlg, IDC_IMPMSN ); + importProt[2] = IsDlgButtonChecked( hdlg, IDC_IMPAIM ); + importProt[3] = IsDlgButtonChecked( hdlg, IDC_IMPYAHOO ); + importNic = IsDlgButtonChecked( hdlg, IDC_IMPIRC ); + importCha = IsDlgButtonChecked( hdlg, IDC_IMPCHA ); + importProt[4] = importNic || importCha; + importMsg = IsDlgButtonChecked( hdlg, IDC_IMPMSG ); + importStat = IsDlgButtonChecked( hdlg, IDC_IMPSTAT ); + importAdd = IsDlgButtonChecked( hdlg, IDC_IMPADD ); + importEx = IsDlgButtonChecked( hdlg, IDC_IMPEX ); + skipDup = IsDlgButtonChecked( hdlg, IDC_SKIPDUP ); + repDup = IsDlgButtonChecked( hdlg, IDC_REPDUP ); + delBefore = IsDlgButtonChecked( hdlg, IDC_DELBEF ); + speedMode = IsDlgButtonChecked( hdlg, IDC_SPEEDMODE ); + utf8AutoDetect = IsDlgButtonChecked( hdlg, IDC_UTF8AUTO ); + utf8DoAlways = IsDlgButtonChecked( hdlg, IDC_UTF8ALWAYS ); + GetDlgItemText( hdlg, IDC_LOGDIR, file, MAX_PATH-1 ); + GetDlgItemText( hdlg, IDC_DELBEFDATE, delBeforeDate, MAX_PATH-1 ); + time = string2Tm( delBeforeDate ); + delBeforeTS = mktime( &time ); + fl = fopen( "importTrillian.ini", "w" ); + if( fl ) + { + fprintf( fl, "%s", file ); + fclose( fl ); + } + if( ( importProt[0] || importProt[1] || importProt[2] || importProt[3] || importProt[4] ) && ( importMsg || importStat ) ) + { + PostMessage( hdlg, WM_CLOSE, 0, 0 ); + DestroyWindow(hdlg); + ImportMessages( ); + } + else + MessageBox( hdlg, Translate( "There's nothing to import, please\nselect a protocol." ), Translate( "Invalid settings" ), 0 ); + } break; + case IDCANCEL: + PostMessage( hdlg, WM_CLOSE, 0, 0 ); + break; + } + break; + case WM_CLOSE: + DestroyWindow(hdlg); + aborting = 1; + break; + } + return FALSE; +} + +BOOL CALLBACK ProgressDialogProc( HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam ) +{ + switch( message ) + { + case WM_INITDIALOG: + SetWindowText( hdlg, Translate( "Importing History" ) ); + + SetDlgItemText( hdlg, IDC_INFO5, Translate( "Import in progress..." ) ); + SetDlgItemText( hdlg, IDC_INFO6, Translate( "Overall (current protocol)" ) ); + SetDlgItemText( hdlg, IDC_INFO7, Translate( "File" ) ); + + SetDlgItemText( hdlg, IDOK, Translate( "OK" ) ); + SetDlgItemText( hdlg, IDCANCEL, Translate( "Cancel" ) ); + + ShowWindow( hdlg, SW_SHOW ); + SendMessage( hdlg, WM_SETICON, ICON_BIG, (LPARAM)LoadIcon( hInst,MAKEINTRESOURCE(IDI_IMPORT) ) ); + return TRUE; + case WM_COMMAND: + switch( LOWORD( wParam ) ) + { + case IDOK: + if( finished ) + PostMessage( hdlg, WM_CLOSE, 0, 0 ); + break; + case IDCANCEL: + { + int ret; + ret = MessageBox( hdlg, Translate( "WARNING: If you cancel now and continue later you might\nget duplicate entries. Cancel anyways?" ), Translate( "Warning" ), MB_YESNO ); + if( ret == IDYES ) + PostMessage( hdlg, WM_CLOSE, 0, 0 ); + break; + } + } + break; + case DLG_UPDATE: + SendDlgItemMessage( hdlg, IDC_STATUS, WM_SETTEXT, 0, (DWORD)status ); + SendDlgItemMessage( hdlg, IDC_FILEP, PBM_SETPOS, wParam, 0 ); + SendDlgItemMessage( hdlg, IDC_OVERP, PBM_SETPOS, lParam, 0 ); + break; + case WM_CLOSE: + DestroyWindow( hdlg ); + aborting = 1; + break; + } + return FALSE; +} + +HANDLE GetContactByID( char* proto, char *idname, char* id ) +{ + HANDLE contact; + char *otherproto; + DBVARIANT dbv; + DWORD idnum = atol(id); + + contact = (HANDLE)CallService( MS_DB_CONTACT_FINDFIRST, 0, 0 ); + while( contact != NULL) + { + otherproto = (char*)CallService( MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)contact, 0 ); + if( ( otherproto != NULL ) && !strcmp( otherproto, proto ) ) + { + if( !DBGetContactSetting( contact, proto, idname, &dbv ) ) + { + switch( dbv.type ) + { + case DBVT_BYTE: + if( dbv.bVal == idnum ) + return contact; + break; + case DBVT_WORD: + if( dbv.wVal == idnum ) + return contact; + break; + case DBVT_DWORD: + if( dbv.dVal == idnum ) + return contact; + break; + default: + case DBVT_ASCIIZ: + if( !strcmp( id, dbv.pszVal ) ) + { + DBFreeVariant( &dbv ); + return contact; + } + break; + } + } + } + contact = (HANDLE)CallService( MS_DB_CONTACT_FINDNEXT, (WPARAM)contact, 0 ); + } + return INVALID_HANDLE_VALUE; +} + +HANDLE DeleteContactEventsBefore( HANDLE hContact, time_t ts ) +{ + HANDLE hDbEvent, hPrev; + DBEVENTINFO dbei; + + if( !( hDbEvent = (HANDLE)CallService( MS_DB_EVENT_FINDFIRST, (WPARAM)hContact, 0 ) ) ) + return INVALID_HANDLE_VALUE; + + while( hDbEvent != NULL ) + { + ZeroMemory( &dbei, sizeof(dbei) ); + dbei.cbSize = sizeof(dbei); + dbei.cbBlob = 0; + CallService( MS_DB_EVENT_GET, (WPARAM)hDbEvent, (LPARAM)&dbei ); + + hPrev = hDbEvent; + hDbEvent = (HANDLE)CallService( MS_DB_EVENT_FINDNEXT, (WPARAM)hDbEvent, 0 ); + if( (time_t)dbei.timestamp < ts ) + CallService( MS_DB_EVENT_DELETE, (WPARAM)hContact, (LPARAM)hPrev ); + } + return INVALID_HANDLE_VALUE; +} + +//***************************************** +// MODIFIED CODE FROM THE IMPORT.DLL PLUGIN! +//***************************************** +HANDLE IsDuplicateEvent(HANDLE hContact, DBEVENTINFO dbei ) +{ + HANDLE hExistingDbEvent; + DBEVENTINFO dbeiExisting; + + if( !( hExistingDbEvent = (HANDLE)CallService( MS_DB_EVENT_FINDLAST, (WPARAM)hContact, 0 ) ) ) + return INVALID_HANDLE_VALUE; + ZeroMemory( &dbeiExisting, sizeof(dbeiExisting) ); + dbeiExisting.cbSize = sizeof(dbeiExisting); + dbeiExisting.cbBlob = 0; + CallService( MS_DB_EVENT_GET, (WPARAM)hExistingDbEvent, (LPARAM)&dbeiExisting ); + if( dbei.timestamp > dbeiExisting.timestamp ) + return INVALID_HANDLE_VALUE; + + if( !( hExistingDbEvent = (HANDLE)CallService( MS_DB_EVENT_FINDFIRST, (WPARAM)hContact, 0 ) ) ) + return INVALID_HANDLE_VALUE; + ZeroMemory( &dbeiExisting, sizeof(dbeiExisting) ); + dbeiExisting.cbSize = sizeof(dbeiExisting); + dbeiExisting.cbBlob = 0; + CallService( MS_DB_EVENT_GET, (WPARAM)hExistingDbEvent, (LPARAM)&dbeiExisting ); + if( dbei.timestamp < dbeiExisting.timestamp ) + return INVALID_HANDLE_VALUE; + + + while( hExistingDbEvent != NULL ) + { + char *blob; + ZeroMemory( &dbeiExisting, sizeof(dbeiExisting) ); + dbeiExisting.cbSize = sizeof(dbeiExisting); + dbeiExisting.cbBlob = CallService( MS_DB_EVENT_GETBLOBSIZE, (WPARAM)hExistingDbEvent, (LPARAM)0 ); + blob = malloc( dbeiExisting.cbBlob ); + dbeiExisting.pBlob = blob; + CallService( MS_DB_EVENT_GET, (WPARAM)hExistingDbEvent, (LPARAM)&dbeiExisting ); + if( dbei.timestamp < dbeiExisting.timestamp ) + { + free( blob ); + return INVALID_HANDLE_VALUE; + } + // Compare event with import candidate + if( ( dbei.timestamp == dbeiExisting.timestamp ) && + ( dbei.eventType == dbeiExisting.eventType ) && + ( dbei.cbBlob == dbeiExisting.cbBlob ) ) + { + if( !strcmp( dbei.pBlob, dbeiExisting.pBlob ) ) + { + free( blob ); + return hExistingDbEvent; + } + } + free( blob ); + // Get next event in chain + hExistingDbEvent = (HANDLE)CallService( MS_DB_EVENT_FINDNEXT, (WPARAM)hExistingDbEvent, 0 ); + } + return INVALID_HANDLE_VALUE; +} + +HANDLE AddNumericContact( char* pszProtoName, char* pszUniqueSetting, DWORD dwID, char* pzsNick ) +{ + HANDLE hContact = INVALID_HANDLE_VALUE; + hContact = (HANDLE)CallService( MS_DB_CONTACT_ADD, 0, 0 ); + if( CallService( MS_PROTO_ADDTOCONTACT, (WPARAM)hContact, (LPARAM)pszProtoName ) != 0 ) + { + CallService( MS_DB_CONTACT_DELETE, (WPARAM)hContact, 0 ); + return INVALID_HANDLE_VALUE; + } + DBWriteContactSettingDword( hContact, pszProtoName, pszUniqueSetting, dwID ); + if( pzsNick && pzsNick[0] ) + DBWriteContactSettingString( hContact, "CList", "MyHandle", pzsNick ); + return hContact; +} + +HANDLE AddContact( char* pszProtoName, char* pszUniqueSetting, char* pszID, char* pzsNick ) +{ + HANDLE hContact = INVALID_HANDLE_VALUE; + hContact = (HANDLE)CallService( MS_DB_CONTACT_ADD, 0, 0 ); + if( CallService( MS_PROTO_ADDTOCONTACT, (WPARAM)hContact, (LPARAM)pszProtoName ) != 0 ) + { + CallService( MS_DB_CONTACT_DELETE, (WPARAM)hContact, 0 ); + return INVALID_HANDLE_VALUE; + } + DBWriteContactSettingString( hContact, pszProtoName, pszUniqueSetting, pszID ); + if( pzsNick && pzsNick[0] ) + DBWriteContactSettingString( hContact, "CList", "MyHandle", pzsNick ); + return hContact; +} + +// szIn, pointer to source string +// szOut, pointer to destination buffer +// cchOut, size of destination buffer +void Utf8ToAnsi( const char *szIn, char *szOut, int cchOut ) +{ + if( GetVersion( ) != 4 || !( GetVersion( ) & 0x80000000 ) ) + { + WCHAR *wszTemp; + int inlen; + inlen = (int)strlen(szIn); + wszTemp = (WCHAR *)malloc( sizeof(WCHAR) * (inlen + 1) ); + MultiByteToWideChar( CP_UTF8, 0, szIn, -1, wszTemp, inlen + 1 ); + WideCharToMultiByte( CP_ACP, 0, wszTemp, -1, szOut, cchOut, NULL, NULL ); + free(wszTemp); + } + else + { + for( ; *szIn && cchOut > 1; szIn++ ) + { + if( *szIn >= 0 ) + { + *szOut++ = *szIn; + cchOut--; + } + else + { + unsigned short wideChar; + if( (unsigned char)*szIn >= 0xe0 ) + { + wideChar = ((szIn[0]&0x0f) << 12) + | ((szIn[1]&0x3f) << 6) + | (szIn[2]&0x3f); + szIn += 2; + } + else + { + wideChar = ( (szIn[0]&0x1f) << 6 ) | ( szIn[1]&0x3f ); + szIn++; + } + if( wideChar >= 0x100 ) *szOut++ = '?'; + else *szOut++ = (char)wideChar; + cchOut--; + } + } + *szOut = '\0'; + } +} +//***************************************** +// END CODE FROM THE IMPORT.DLL PLUGIN! +//***************************************** + +BOOL importSingleHistory( char *logpath, HANDLE *hContact, char *prot, HWND *dlg, float overal ) +{ + int i = 0, lineNr, lineTotal = 0, lastflag = 0, imp = 0; + char *time; + char *message; + DBEVENTINFO dbev; + HANDLE dup; + FILE *msg; + char other[256]; + time_t startts, prev = 0; + struct tm starttime; + int hasTime = -1, timeType = 0; + int nameoffset[2][2] = { { 0, 8 }, { 0, 11 } }; + BOOL doConversion = FALSE; + MSG pm; + + msg = fopen( logpath, "r" ); + lineTotal = 0; + startts = 0; + if( msg ) + { + while( !feof( msg ) ) + { + if( fgetc( msg ) == '\n' ) + lineTotal++; + } + fseek( msg, 0, SEEK_SET ); + + lineNr = 0; + imp = FALSE; + } + lineTotal = max( 1, lineTotal ); + while( msg && readLine( msg ) ) + { + if( aborting ) + return FALSE; + lineNr++; + ZeroMemory( &dbev, sizeof( dbev ) ); + dbev.cbSize = sizeof(dbev); + dbev.eventType = EVENTTYPE_MESSAGE; + dbev.szModule = prot; + + if( !( lineNr % 10 ) ) + { + SendMessage( *dlg, DLG_UPDATE, 100 * lineNr / lineTotal, (LPARAM)overal ); + wsprintf( status, "%s: %s %d/~%d", logpath, Translate( "line" ), lineNr, lineTotal ); + } + + if( !strlen( line ) ) + { + } + // Inefficient but quite save. + else if( strstr( line, SESS_START1 ) + || strstr( line, SESS_START2 ) + || strstr( line, SESS_START3 ) + || strstr( line, SESS_START4 ) + || strstr( line, SESS_START5 ) ) + { + if( !strrchr( line, ')' ) ) + continue; + time = strrchr( line, ')' ) + 7; + starttime = string2Tm( time ); + startts = mktime( &starttime ); + + hasTime = -1; + + strncpy( other, strchr( line, ':' ) + 1, 255 ); + if( strrchr( other, ')' ) ) + *strrchr( other, ')' ) = '\0'; + strcpy( lastNick, other ); + } + else if( strstr( line, SESS_STOP ) ) + { + } + else if( startts ) + { + //FILE *f; + if( hasTime == -1 ) + { + hasTime = 0; + if( line[0] == '[' && strncmp( line, other, strlen(other) ) ) + { + int timelen = ( (int)strchr( line, ']' ) - (int)line ); + if( timelen == 9 ) + { + hasTime = 1; + timeType = 1; + } + else if( timelen == 6 ) + { + hasTime = 1; + timeType = 0; + } + } + } + + /*f = fopen( "test.log", "w" ); + fprintf( f, "%s\n%s", &line[nameoffset[timeType][hasTime]], other ); + fclose( f );*/ + if( hasTime && line[0] != '[' ) + { + if( !importMsg ) + continue; + message = line; + dbev.flags = lastflag; + } + else if( !strncmp( &line[nameoffset[timeType][hasTime]], other, strlen(other) ) ) + { + if( !importMsg ) + continue; + dbev.flags = DBEF_READ; + message = line + nameoffset[timeType][hasTime] + strlen( other ) + 2; + } + else if( !strncmp( &line[nameoffset[timeType][hasTime]], "*** ", 4 ) ) + { + if( !importStat ) + continue; + dbev.flags = DBEF_READ; + message = line + nameoffset[timeType][hasTime]; + } + else + { + if( !importMsg ) + continue; + message = strchr( line + nameoffset[timeType][hasTime], ':' ) + 2; + if( (int)message == 2 ) + message = line + nameoffset[timeType][hasTime] + 1; + dbev.flags = DBEF_SENT | DBEF_READ; + } + + if( hasTime && line[0] == '[' && line[3] == ':') + { + int hr, min, sec; + if( timeType == 1 ) + { + sscanf( line, "[%d:%d:%d", &hr, &min, &sec ); + starttime.tm_sec = sec; + } + else + { + sscanf( line, "[%d:%d", &hr, &min ); + starttime.tm_sec = 0; + } + starttime.tm_hour = hr; + starttime.tm_min = min; + startts = mktime( &starttime ); + } + //if( startts == prev ) + // startts += 4; + + doConversion = FALSE; + if( utf8AutoDetect ) + { + //Whatever :) + if( strstr( message, "ä" ) + || strstr( message, "ö" ) + || strstr( message, "ü" ) + || strstr( message, "Ä" ) + || strstr( message, "Ö" ) + || strstr( message, "Ü" ) + || strstr( message, "ß" ) + || strstr( message, "é" ) + || strstr( message, "à" ) + || strstr( message, "è" ) + || strstr( message, "É" ) + || strstr( message, "À" ) + || strstr( message, "È" ) + || strstr( message, "ç" ) ) + doConversion = TRUE; + } + else if( utf8DoAlways ) + doConversion = TRUE; + if( doConversion ) + Utf8ToAnsi( message, message, (int)strlen(message) ); + imp = TRUE; + + lastflag = dbev.flags; + dbev.timestamp = (DWORD)startts; + dbev.cbBlob = (DWORD)strlen( message ) + 1; + dbev.pBlob = (PBYTE)malloc( dbev.cbBlob ); + CopyMemory( dbev.pBlob, message, dbev.cbBlob ); + dbev.pBlob[dbev.cbBlob - 1] = 0; + if( ( dup = IsDuplicateEvent( *hContact, dbev ) ) == INVALID_HANDLE_VALUE ) + CallService( MS_DB_EVENT_ADD, (WPARAM)*hContact, (LPARAM)&dbev ); + else if( repDup ) + { + CallService( MS_DB_EVENT_DELETE, (WPARAM)*hContact, (LPARAM)dup ); + CallService( MS_DB_EVENT_ADD, (WPARAM)*hContact, (LPARAM)&dbev ); + } + else + wsprintf( status, "Skipping dublicate entries..." ); + + prev = startts; + free( dbev.pBlob ); + } + if( PeekMessage( &pm, NULL, 0, 0, PM_REMOVE ) ) + { + TranslateMessage( &pm ); + DispatchMessage( &pm ); + } + } + if( msg ) + fclose( msg ); + return imp; +} + +struct import +{ + char prot[8]; + char id[8]; + int num; +}; + +int numFiles( char *path ) +{ + struct _finddata_t fl; + long curFl; + int num = 0; + + if( ( curFl = (long)_findfirst( path, &fl ) ) == -1L ) + return num; + + while( _findnext( curFl, &fl ) == 0 ) + { + num++; + } + _findclose( curFl ); + return num; +} + +struct import importList[6] = +{ + { "ICQ", "UIN", 1 }, + { "MSN", "e-mail", 0 }, + { "AIM", "SN", 0 }, + { "YAHOO", "yahoo_id", 0 }, + { "IRC", "Nick", 0 }, + { "", "", 0 } +}; + +static int ImportMessages( ) +{ + int i = 0, numImp = 0, contTotal = 0, contNr = 0, o; + HANDLE hContact; + char msgpath[128]; + char id[64]; + HWND dlg; + MSG pm; + struct _finddata_t fl; + long curFl; + int len, first = 1; + + aborting = 0; + finished = 0; + + dlg = CreateDialog( hInst, MAKEINTRESOURCE(IDD_TRILLIAN), NULL, (DLGPROC)ProgressDialogProc ); + //contTotal = (int)CallService( MS_DB_CONTACT_GETCOUNT, 0, 0 ); + + if( speedMode ) + CallService( MS_DB_SETSAFETYMODE, (WPARAM)FALSE, 0 ); + + while( !aborting && strlen( importList[i].prot ) ) + { + if( !importProt[i] ) + { + i++; + continue; + } + for( o = 0; o < 2; o++ ) + { + first = 1; + contNr = -1; + sprintf( msgpath, "%s\\%s%s\\*.log", file, importList[i].prot, o == 0 ? "" : "\\Query" ); + contTotal = numFiles( msgpath ); + + curFl = (long)_findfirst( msgpath, &fl ); + //if( ( curFl = (long)_findfirst( msgpath, &fl ) ) == -1L ) + // MessageBox( dlg, Translate( "No logs found for this protocol." ), importList[i].prot, 0 ); + + while( !aborting && ( ( first && curFl != -1 ) || ( _findnext( curFl, &fl ) == 0 ) ) ) + { + first = 0; + contNr++; + if( !strncmp( fl.name, importList[i].prot, strlen( importList[i].prot ) ) ) + continue; + if( !strcmp( importList[i].prot, "IRC" ) ) + { + if( strchr( fl.name, '#' ) ) + { + if( !importCha ) + continue; + } + else if( !importNic ) + continue; + } + len = (long)strrchr( fl.name, '.' ) - (long)fl.name; + strncpy( id, fl.name, len ); + id[len] = '\0'; + getNick = FALSE; + + hContact = GetContactByID( importList[i].prot, importList[i].id, id ); + + sprintf( msgpath, "%s\\%s%s\\%s.log", file, importList[i].prot, o == 0 ? "" : "\\Query", id ); + if( ( hContact == INVALID_HANDLE_VALUE ) && importAdd ) + { + if( importList[i].num ) + hContact = AddNumericContact( importList[i].prot, importList[i].id, atol(id), 0 ); + else + hContact = AddContact( importList[i].prot, importList[i].id, id, 0 ); + getNick = TRUE; + } + else if( !importEx ) + continue; + if( delBefore ) + DeleteContactEventsBefore( hContact, delBeforeTS ); + if( ( hContact != INVALID_HANDLE_VALUE ) && importSingleHistory( msgpath, &hContact, importList[i].prot, &dlg, 100.0f * contNr / contTotal ) ) + numImp++; + if( getNick ) + DBWriteContactSettingString( hContact, "CList", "MyHandle", lastNick ); + } + _findclose( curFl ); + } + i++; + } + + if( speedMode ) + CallService( MS_DB_SETSAFETYMODE, (WPARAM)TRUE, 0 ); + + finished = 1; + + wsprintf( status, Translate( "Done importing %d contact history files!" ), numImp ); + if( numImp == 0 ) + strcat( status, Translate( "\nCheck your UIN and path settings. Path musst end with \\logs" ) ); + SendMessage( dlg, DLG_UPDATE, 100, 100 ); + + while( PeekMessage( &pm, NULL, 0, 0, PM_REMOVE ) ) + { + TranslateMessage( &pm ); + DispatchMessage( &pm ); + } + return 0; +} + +static int ImportCommand( WPARAM wParam,LPARAM lParam ) +{ + HWND dlg; + strcpy( file, "C:\\Program Files\\Trillian\\users\\default\\logs" ); + dlg = CreateDialog( hInst, MAKEINTRESOURCE(IDD_STARTUP), NULL, (DLGPROC)StartupDialogProc ); + return 0; +} + +__declspec(dllexport) PLUGININFO* MirandaPluginInfo( DWORD mirandaVersion ) +{ + if (mirandaVersion < PLUGIN_MAKE_VERSION(0, 1, 1, 0)) + return NULL; + + return &pluginInfo; +} + +int __declspec(dllexport) Load( PLUGINLINK *link ) +{ + CLISTMENUITEM mi; + + pluginLink = link; + CreateServiceFunction( IMPORT_SERVICE, ImportCommand ); + + ZeroMemory( &mi, sizeof( mi ) ); + mi.cbSize = sizeof( mi ); + mi.hIcon = LoadIcon(hInst, MAKEINTRESOURCE(IDI_IMPORT)); + mi.pszName = Translate( Translate( "Import Trillian history/contacts..." ) ); + mi.position = 500050000; + mi.pszService = IMPORT_SERVICE; + CallService( MS_CLIST_ADDMAINMENUITEM, 0, (LPARAM)&mi ); + return 0; +} + + +int __declspec(dllexport) Unload( void ) +{ + return 0; +} \ No newline at end of file diff --git a/ImportTrillian/resource.h b/ImportTrillian/resource.h new file mode 100644 index 0000000..a588d3b --- /dev/null +++ b/ImportTrillian/resource.h @@ -0,0 +1,69 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by resource.rc +// +#define IDC_BACK 3 +#define IDD_TRILLIAN 105 +#define IDD_DIALOG1 106 +#define IDD_STARTUP 106 +#define IDI_IMPORT 177 +#define IDC_MIRABILIS 1000 +#define IDC_DONTLOADPLUGIN 1001 +#define IDC_MIRANDA 1001 +#define IDC_USEFINDADD 1004 +#define IDC_OTHER 1005 +#define IDC_LIST 1006 +#define IDC_FILENAME 1007 +#define IDC_PROGRESS 1008 +#define IDC_FILEP 1008 +#define IDC_STATUS 1009 +#define IDC_MIRABILISRUNNING 1010 +#define IDC_OVERP 1010 +#define IDC_RADIO_ALL 1016 +#define IDC_RADIO_CONTACTS 1017 +#define IDC_STATIC_ALL 1019 +#define IDC_STATIC_CONTACTS 1020 +#define IDC_ICQUIN 1025 +#define IDC_LOGDIR 1027 +#define IDC_BROWSE 1028 +#define IDC_IMPICQ 1029 +#define IDC_IMPMSN 1030 +#define IDC_IMPAIM 1031 +#define IDC_IMPIRC 1032 +#define IDC_IMPMSG 1033 +#define IDC_IMPSTAT 1034 +#define IDC_IMPADD 1035 +#define IDC_IMPEX 1036 +#define IDC_IMPYAHOO 1037 +#define IDC_IMPIRC2 1038 +#define IDC_IMPCHA 1038 +#define IDC_INFO1 1039 +#define IDC_INFO2 1040 +#define IDC_INFO3 1041 +#define IDC_INFO4 1042 +#define IDC_INFO5 1043 +#define IDC_SKIPDUP 1043 +#define IDC_INFO6 1044 +#define IDC_IMPSTAT2 1044 +#define IDC_SPEEDMODE 1044 +#define IDC_REPDUP 1045 +#define IDC_DELBEFDATE 1046 +#define IDC_DELBEF 1047 +#define IDC_UTF8ALWAYS 1048 +#define IDC_UTF8h 1049 +#define IDC_UTF8AUTO 1049 +#define IDC_UTF8 1050 +#define IDC_STATIC -1 +#define IDC_INFO7 -1 +#define IDC_DELBEFINFO -1 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 107 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1051 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/ImportTrillian/resource.rc b/ImportTrillian/resource.rc new file mode 100644 index 0000000..ce5e864 --- /dev/null +++ b/ImportTrillian/resource.rc @@ -0,0 +1,247 @@ +// Microsoft Visual C++ generated resource script. +// +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// German (Switzerland) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_DES) +#ifdef _WIN32 +LANGUAGE LANG_GERMAN, SUBLANG_GERMAN_SWISS +#pragma code_page(1252) +#endif //_WIN32 + +///////////////////////////////////////////////////////////////////////////// +// +// DESIGNINFO +// + +#ifdef APSTUDIO_INVOKED +GUIDELINES DESIGNINFO +BEGIN + IDD_TRILLIAN, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 265 + TOPMARGIN, 7 + BOTTOMMARGIN, 83 + END + + IDD_STARTUP, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 239 + TOPMARGIN, 7 + BOTTOMMARGIN, 246 + END +END +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +IDD_TRILLIAN DIALOGEX 0, 0, 272, 90 +STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | + WS_CAPTION +CAPTION "Importing History" +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + DEFPUSHBUTTON "OK",IDOK,215,7,50,14,BS_FLAT + PUSHBUTTON "Cancel",IDCANCEL,215,24,50,14,BS_FLAT + LTEXT "Import in progress...",IDC_INFO5,7,7,85,9 + LTEXT "Static",IDC_STATUS,7,22,206,22 + CONTROL "",IDC_FILEP,"msctls_progress32",WS_BORDER | 0x1,7,75, + 197,8 + LTEXT "File",IDC_INFO7,7,64,48,8 + CONTROL "",IDC_OVERP,"msctls_progress32",WS_BORDER | 0x1,7,55, + 197,8 + LTEXT "Overall (current protocol)",IDC_INFO6,7,47,118,8 +END + +IDD_STARTUP DIALOGEX 0, 0, 246, 254 +STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | + WS_CAPTION +CAPTION "Import settings" +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + PUSHBUTTON "Cancel",IDCANCEL,64,65,50,14,BS_FLAT + EDITTEXT IDC_LOGDIR,7,17,232,12,ES_AUTOHSCROLL | NOT WS_BORDER, + WS_EX_STATICEDGE + LTEXT "Trillian logs directory",IDC_INFO1,7,7,67,8 + PUSHBUTTON "Browse",IDC_BROWSE,75,7,32,10,BS_FLAT + CONTROL "Import ICQ history",IDC_IMPICQ,"Button",BS_AUTOCHECKBOX | + BS_FLAT | WS_TABSTOP,12,94,81,8 + CONTROL "Import MSN history",IDC_IMPMSN,"Button",BS_AUTOCHECKBOX | + BS_FLAT | WS_TABSTOP,12,109,82,8 + CONTROL "Import AIM history",IDC_IMPAIM,"Button",BS_AUTOCHECKBOX | + BS_FLAT | WS_TABSTOP,12,124,82,8 + DEFPUSHBUTTON "Start",IDOK,7,65,50,14,BS_FLAT + CONTROL "Import messages",IDC_IMPMSG,"Button",BS_AUTOCHECKBOX | + BS_FLAT | WS_TABSTOP,108,143,123,8 + CONTROL "Import status reports (filetransfers, away msg, etc.)", + IDC_IMPSTAT,"Button",BS_AUTOCHECKBOX | BS_MULTILINE | + BS_FLAT | WS_TABSTOP,108,178,128,16 + GROUPBOX "Protocols",IDC_INFO2,7,84,91,124 + GROUPBOX "Contacts",IDC_INFO3,103,84,136,46 + CONTROL "Import IRC history",IDC_IMPIRC,"Button",BS_AUTOCHECKBOX | + BS_FLAT | WS_TABSTOP,12,155,78,8 + CONTROL "Add new contacts if a contact from the history is not on the list", + IDC_IMPADD,"Button",BS_AUTOCHECKBOX | BS_MULTILINE | + BS_FLAT | WS_TABSTOP,108,110,126,16 + CONTROL "Import history of existing contacts",IDC_IMPEX,"Button", + BS_AUTOCHECKBOX | BS_MULTILINE | BS_FLAT | WS_TABSTOP, + 108,94,125,14 + CONTROL "Import Yahoo! history",IDC_IMPYAHOO,"Button", + BS_AUTOCHECKBOX | BS_FLAT | WS_TABSTOP,12,139,84,8 + CONTROL "Import IRC channel history",IDC_IMPCHA,"Button", + BS_AUTOCHECKBOX | BS_MULTILINE | BS_FLAT | WS_TABSTOP,12, + 168,78,16 + GROUPBOX "Import",IDC_INFO4,103,133,136,75 + CONTROL "Skip duplicate messages",IDC_SKIPDUP,"Button", + BS_AUTOCHECKBOX | BS_FLAT | WS_TABSTOP,108,155,123,8 + CONTROL "Fast mode (backup your db!)",IDC_SPEEDMODE,"Button", + BS_AUTOCHECKBOX | BS_MULTILINE | BS_FLAT | WS_TABSTOP, + 108,195,128,8 + CONTROL "Replace duplicate messages",IDC_REPDUP,"Button", + BS_AUTOCHECKBOX | BS_FLAT | WS_TABSTOP,108,168,123,8 + EDITTEXT IDC_DELBEFDATE,93,32,146,12,ES_AUTOHSCROLL | NOT + WS_BORDER,WS_EX_STATICEDGE + CONTROL "Delete entries before",IDC_DELBEF,"Button", + BS_AUTOCHECKBOX | BS_FLAT | WS_TABSTOP,8,35,83,8 + LTEXT "(Must match this format exactly: MMM DD HH:mm:ss YYYY)", + IDC_DELBEFINFO,7,47,232,11 + GROUPBOX "UTF8",IDC_UTF8,7,211,232,35 + CONTROL "Interpret logs as UTF8 files",IDC_UTF8ALWAYS,"Button", + BS_AUTOCHECKBOX | BS_MULTILINE | BS_FLAT | WS_TABSTOP,13, + 222,128,8 + CONTROL "Try to auto-detect UTF8 strings (is slow, detects öäüßéàèç)", + IDC_UTF8AUTO,"Button",BS_AUTOCHECKBOX | BS_MULTILINE | + BS_FLAT | WS_TABSTOP,13,234,209,8 +END + +#endif // German (Switzerland) resources +///////////////////////////////////////////////////////////////////////////// + + +///////////////////////////////////////////////////////////////////////////// +// English (U.K.) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENG) +#ifdef _WIN32 +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_UK +#pragma code_page(1252) +#endif //_WIN32 + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE +BEGIN + "#include \r\n" + "\0" +END + +3 TEXTINCLUDE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + +#endif // English (U.K.) resources +///////////////////////////////////////////////////////////////////////////// + + +///////////////////////////////////////////////////////////////////////////// +// English (Australia) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENA) +#ifdef _WIN32 +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_AUS +#pragma code_page(1252) +#endif //_WIN32 + +///////////////////////////////////////////////////////////////////////////// +// +// Icon +// + +// Icon with lowest ID value placed first to ensure application icon +// remains consistent on all systems. +IDI_IMPORT ICON "import.ico" + +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +VS_VERSION_INFO VERSIONINFO + FILEVERSION 0,2,0,0 + PRODUCTVERSION 0,0,0,0 + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x40004L + FILETYPE 0x2L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "000004b0" + BEGIN + VALUE "Comments", "Licensed under the terms of the GNU General Public License" + VALUE "CompanyName", " " + VALUE "FileDescription", "Miranda IM Message/Contact Import Plugin" + VALUE "FileVersion", "0.2.0" + VALUE "InternalName", "importTrillian" + VALUE "LegalCopyright", "Copyright © 2006 Daniel 'Zpin' Hofer" + VALUE "OriginalFilename", "importTrillian.dll" + VALUE "ProductVersion", "0, 0, 0, 0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x0, 1200 + END +END + +#endif // English (Australia) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + -- cgit v1.2.3