summaryrefslogtreecommitdiffstats
path: root/kmail/kmail-3.3-use-ID-for-accounts.pl
blob: 8270a57f02394b081a6f00a0593798ef69d188b6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
#!/usr/bin/perl -w

use strict;

# this script goes through all the config keys that deal with
# accounts and replaces accounts referenced by name to be referenced
# by IDs. 
# It also renames the toplevel-folder and the sent/trash/drafts folder
# accordingly and renames all references
# last but not least we move the lokal folder-cache of (d)imap folders

# read the whole config file
my $currentGroup = "";
my %configFile;
while ( <> ) {
    chomp;
    next if ( /^$/ ); # skip empty lines
    next if ( /^\#/ ); # skip comments
    if ( /^\[/ ) { # group begin
      $currentGroup = $_;
      next;
    } elsif ( $currentGroup =~ /^\[Account/ and /^Id/ ) {
	  # We need to prevent this script from running twice, since it
      # would change IDs of accounts then.
      # Presence of a id key in an Account section is the
	  # best indicator
      exit;
    } elsif ( $currentGroup ne "" ) { # normal entry
      my ($key,$value) = split /=/;
      $configFile{$currentGroup}{$key}=$value;
    }
}

# filter out account groups
my @accountGroups = grep { /^\[Account \d+\]/ } keys %configFile;

# create IDs for each account
my %nameToID;
my %nameToType;
foreach my $accountGroup (@accountGroups) {
  my $id;
  do {
    $id = int(rand 0x7fFFffFF);
  } while ($id <= 0);
  my $name = $configFile{$accountGroup}{'Name'};
  # remember id and type
  $nameToID{$name} = $id;
  $nameToType{$name} = $configFile{$accountGroup}{'Type'};
  # create the id entries
  print "${accountGroup}\nId=$id\n";
}

foreach my $accountGroup (@accountGroups) {
  # rename the trash
  my $trash = $configFile{$accountGroup}{'trash'};
  if (&replaceID($trash)) {
    print "# DELETE ".$accountGroup."trash\n";
    print "${accountGroup}\ntrash=".&replaceID($trash)."\n";
  }
}

# we need the directory where the imap cache is stored
open(CMD, "kde-config --localprefix|");
my $basedir = <CMD>;
chomp( $basedir );
$basedir = $basedir."share/apps/kmail";

# Now, go through all [Folder-*] groups that belong to (d)imap folders
# and replace the account name with the id
my @folderGroups = grep { /^\[Folder-.*\]/ } keys %configFile;

foreach my $folderGroup ( @folderGroups ) 
{
  my $isRootFolder = 1;
  # extract the accountname
  my (@parts) = split (/\[Folder-/,$folderGroup);
  my $account = substr($parts[1], 0, -1);
  if ($account =~ /^[^\/]*\.directory\//)
  {
    # .account.directory
    my (@dirparts) = split (/\.directory\//,$account);
    $account = substr( $dirparts[0], 1 );
    # this is no root folder
    $isRootFolder = 0;
  }
  # delete the old group and write the new entry
  my $accountDecoded = QFileDecode( $account );
  if ( exists( $nameToID{$accountDecoded} ) )
  {
    my $id = $nameToID{$accountDecoded};
    print "# DELETEGROUP $folderGroup\n";
    my $folderGroupNew = $folderGroup;
    my $pattern = quotemeta( $account );
    $folderGroupNew =~ s/$pattern/$id/;
    # new account section
    print "$folderGroupNew\n";
    # print all original keys
    my %groupData = %{$configFile{$folderGroup}};
    foreach my $key ( keys %groupData ) {
      print "$key=" . $groupData{$key} . "\n";
    }
    if ($isRootFolder) {
      # new label and id of this rootfolder
      print "SystemLabel=$account\n";
      print "Id=".$id."\n";

      # move the directory
      my $subdir;
      if ($nameToType{$accountDecoded} eq "imap") {
        $subdir = "imap";
      } elsif ($nameToType{$accountDecoded} eq "cachedimap") {
        $subdir = "dimap";
      }
      my $oldname = QFileEncode( "$basedir/$subdir/\.$account\.directory" );
      my $systemcall = "mv '$oldname' '$basedir/$subdir/\.".$id."\.directory'";
      system($systemcall);

      $oldname = QFileEncode( "$basedir/$subdir/$account" );
      $systemcall = "mv '$oldname' '$basedir/$subdir/".$id."'";
      system($systemcall);

      $oldname = QFileEncode( "$basedir/$subdir/\.$account\.index" );
      $systemcall = "mv '$oldname' '$basedir/$subdir/\.".$id."\.index'";
      system($systemcall);

      $oldname = QFileEncode( "$basedir/$subdir/\.$account\.index.ids" );
      $systemcall = "mv '$oldname' '$basedir/$subdir/\.".$id."\.index.ids'";
      system($systemcall);
    }
  }
}

# go through all identities and replace the sent-mail and drafts folder
my @identities = grep { /^\[Identity #\d\]/ } keys %configFile;

foreach my $identity (@identities)
{
  my $drafts = $configFile{$identity}{'Drafts'};
  my $sent = $configFile{$identity}{'Fcc'};
  # extract the account name
  if (&replaceID($drafts))
  {
    print "# DELETE ".$identity."Drafts\n";
    print "${identity}\nDrafts=".&replaceID($drafts)."\n";
  }
  if (&replaceID($sent))
  {
    print "# DELETE ".$identity."Fcc\n";
    print "${identity}\nFcc=".&replaceID($sent)."\n";
  }
}

# go through all filters and replace the target
my @filterGroups = grep { /^\[Filter \#\d+\]/ } keys %configFile;
foreach my $filterGroup (@filterGroups) 
{
    my $numActions = +$configFile{$filterGroup}{'actions'};
    # go through all actions in search for "set identity":
    for ( my $i = 0 ; $i < $numActions ; ++$i ) 
    {
      my $actionName = "action-name-$i";
      my $actionArgs = "action-args-$i";
      if ( $configFile{$filterGroup}{$actionName} eq "transfer" &&
           &replaceID($configFile{$filterGroup}{$actionArgs}) ) 
      {
        print "# DELETE $filterGroup$actionArgs\n";
        print "$filterGroup\n$actionArgs=".
          &replaceID($configFile{$filterGroup}{$actionArgs})."\n";
      }
    }
}

# previous fcc
my $pfcc = $configFile{'[Composer]'}{'previous-fcc'};
if (&replaceID($pfcc)) {
  print "# DELETE [Composer]previous-fcc\n";
  print "[Composer]\nprevious-fcc=".&replaceID($pfcc)."\n";
}

# GroupwareFolder
my $groupware = $configFile{'[Groupware]'}{'GroupwareFolder'};
if (&replaceID($groupware)) {
  print "# DELETE [Groupware]GroupwareFolder\n";
  print "[Groupware]\nGroupwareFolder=".&replaceID($groupware)."\n";
}

# and finally the startupFolder
my $startup = $configFile{'[General]'}{'startupFolder'};
if (&replaceID($startup)) {
  print "# DELETE [General]startupFolder\n";
  print "[General]\nstartupFolder=".&replaceID($startup)."\n";
}

## Returns input string with replaced account name
## If there is nothing to replace it returns undef
sub replaceID
{
  my ($input) = @_;

  if ($input && $input =~ /\.directory/)
  {
    my (@dirparts) = split (/\.directory\//,$input);
    my $account = substr( $dirparts[0], 1 );
    my $accountDecoded = QFileDecode( $account );
    if ( exists( $nameToID{$accountDecoded} ) )
    {
      my $pattern = quotemeta( $account );
      $input =~ s/$pattern/$nameToID{$accountDecoded}/;
      return $input;
    }
  }
}

## emulate QFileDecode
sub QFileDecode
{
  my ($input) = @_;

  $input =~ s/%20/ /g;
  $input =~ s/%40/\@/g;
  $input =~ s/%25/%/g;  # must be the last one

  return $input;
}

## emulate QFileEncode
sub QFileEncode
{
  my ($input) = @_;

  $input =~ s/%/%25/g;  # must be the first one
  $input =~ s/ /%20/g;
  $input =~ s/\@/%40/g;

  return $input;
}