user/dev discussion of public-inbox itself
 help / color / mirror / code / Atom feed
* [PATCH 0/2] lei IMAP usability stuff
@ 2021-05-23 21:36 Eric Wong
  2021-05-23 21:36 ` [PATCH 1/2] lei inspect: use LeiMailSync->match_imap_url Eric Wong
  2021-05-23 21:36 ` [PATCH 2/2] lei_mail_sync: reject IMAP URLs w/o UIDVALIDITY Eric Wong
  0 siblings, 2 replies; 3+ messages in thread
From: Eric Wong @ 2021-05-23 21:36 UTC (permalink / raw)
  To: meta

Slowly making IMAP usability less bad.

Eric Wong (2):
  lei inspect: use LeiMailSync->match_imap_url
  lei_mail_sync: reject IMAP URLs w/o UIDVALIDITY

 lib/PublicInbox/LeiExportKw.pm | 43 ++++++----------------------------
 lib/PublicInbox/LeiInspect.pm  | 13 +---------
 lib/PublicInbox/LeiMailSync.pm | 37 +++++++++++++++++++++++++++++
 t/lei-import-imap.t            | 10 ++++++--
 4 files changed, 53 insertions(+), 50 deletions(-)

^ permalink raw reply	[flat|nested] 3+ messages in thread

* [PATCH 1/2] lei inspect: use LeiMailSync->match_imap_url
  2021-05-23 21:36 [PATCH 0/2] lei IMAP usability stuff Eric Wong
@ 2021-05-23 21:36 ` Eric Wong
  2021-05-23 21:36 ` [PATCH 2/2] lei_mail_sync: reject IMAP URLs w/o UIDVALIDITY Eric Wong
  1 sibling, 0 replies; 3+ messages in thread
From: Eric Wong @ 2021-05-23 21:36 UTC (permalink / raw)
  To: meta

Move match_imap_url into LeiMailSync so it can be used in more
places, such as "lei inspect".  Upcoming commands such as
"lei forget-mail-sync" and {add,forget,pause,resume}-watch will
also support relaxed IMAP matching rules since there's
no reasonable way to expect users use ";UIDVALIDITY=" on the
command-line.
---
 lib/PublicInbox/LeiExportKw.pm | 43 ++++++----------------------------
 lib/PublicInbox/LeiInspect.pm  | 13 +---------
 lib/PublicInbox/LeiMailSync.pm | 32 +++++++++++++++++++++++++
 t/lei-import-imap.t            | 10 ++++++--
 4 files changed, 48 insertions(+), 50 deletions(-)

diff --git a/lib/PublicInbox/LeiExportKw.pm b/lib/PublicInbox/LeiExportKw.pm
index 82a4db04..404570c5 100644
--- a/lib/PublicInbox/LeiExportKw.pm
+++ b/lib/PublicInbox/LeiExportKw.pm
@@ -75,7 +75,7 @@ sub input_path_url {
 		my $mdir = $1;
 		require PublicInbox::LeiToMail; # kw2suffix
 		$lms->each_src($input, \&export_kw_md, $self, $mdir);
-	} elsif ($input =~ m!\Aimaps?://!) {
+	} elsif ($input =~ m!\Aimaps?://i!) {
 		my $uri = PublicInbox::URIimap->new($input);
 		my $mic = $self->{nwr}->mic_for_folder($uri);
 		$lms->each_src($$uri, \&export_kw_imap, $self, $mic);
@@ -84,37 +84,6 @@ sub input_path_url {
 	$lms->lms_commit;
 }
 
-sub match_imap_url ($$) {
-	my ($all, $url) = @_; # $all = [ $lms->folders ];
-	require PublicInbox::URIimap;
-	my $cli = PublicInbox::URIimap->new($url)->canonical;
-	my ($s, $h, $mb) = ($cli->scheme, $cli->host, $cli->mailbox);
-	my @uri = map { PublicInbox::URIimap->new($_)->canonical }
-		grep(m!\A\Q$s\E://.*?\Q$h\E\b.*?/\Q$mb\E\b!, @$all);
-	my @match;
-	for my $x (@uri) {
-		next if $x->mailbox ne $cli->mailbox;
-		next if $x->host ne $cli->host;
-		next if $x->port != $cli->port;
-		my $x_uidval = $x->uidvalidity;
-		next if ($cli->uidvalidity // $x_uidval) != $x_uidval;
-
-		# allow nothing in CLI to possibly match ";AUTH=ANONYMOUS"
-		if (defined($x->auth) && !defined($cli->auth) &&
-				!defined($cli->user)) {
-			push @match, $x;
-		# or maybe user was forgotten on CLI:
-		} elsif (defined($x->user) && !defined($cli->user)) {
-			push @match, $x;
-		} elsif (($x->user//"\0") eq ($cli->user//"\0")) {
-			push @match, $x;
-		}
-	}
-	return $match[0] if scalar(@match) <= 1;
-	warn "E: `$url' is ambiguous:\n\t", join("\n\t", @match), "\n";
-	undef;
-}
-
 sub lei_export_kw {
 	my ($lei, @folders) = @_;
 	my $sto = $lei->_lei_store or return $lei->fail(<<EOM);
@@ -166,12 +135,14 @@ EOM
 				$_ = $d;
 			} elsif (m!\Aimaps?://!i) {
 				my $orig = $_;
-				if (my $canon = match_imap_url(\@all, $orig)) {
+				my $res = $lms->match_imap_url($orig, $all);
+				if (ref $res) {
+					$_ = $$res;
 					$lei->qerr(<<EOM);
-# using `$canon' instead of `$orig'
+# using `$res' instead of `$orig'
 EOM
-					$_ = $canon;
 				} else {
+					$lei->err($res) if defined $res;
 					push @no, $orig;
 				}
 			} else {
@@ -188,7 +159,7 @@ EOF
 	$lei->{opt}->{'mail-sync'} = 1; # for prepare_inputs
 	$self->prepare_inputs($lei, \@folders) or return;
 	my $j = $opt->{jobs} // scalar(@{$self->{inputs}}) || 1;
-	if (my @ro = grep(!/\A(?:maildir|imaps?):/, @folders)) {
+	if (my @ro = grep(!/\A(?:maildir|imaps?):/i, @folders)) {
 		return $lei->fail("cannot export to read-only folders: @ro");
 	}
 	my $m = $opt->{mode} // 'merge';
diff --git a/lib/PublicInbox/LeiInspect.pm b/lib/PublicInbox/LeiInspect.pm
index f79ebc9a..7fd33289 100644
--- a/lib/PublicInbox/LeiInspect.pm
+++ b/lib/PublicInbox/LeiInspect.pm
@@ -31,18 +31,7 @@ sub inspect_sync_folder ($$) {
 	my $lms = $lse->lms or return $ent;
 	my @folders;
 	if ($folder =~ m!\Aimaps?://!i) {
-		require PublicInbox::URIimap;
-		my $uri = PublicInbox::URIimap->new($folder)->canonical;
-		if (defined($uri->uidvalidity)) {
-			$folders[0] = $$uri;
-		} else {
-			my @maybe = $lms->folders($$uri);
-			@folders = grep {
-				my $u = PublicInbox::URIimap->new($_);
-				$uri->uidvalidity($u->uidvalidity);
-				$$uri eq $$u;
-			} @maybe;
-		}
+		@folders = map { $_->as_string } $lms->match_imap_url($folder);
 	} elsif ($folder =~ m!\A(maildir|mh):(.+)!i) {
 		my $type = lc $1;
 		$folders[0] = "$type:".$lei->abs_path($2);
diff --git a/lib/PublicInbox/LeiMailSync.pm b/lib/PublicInbox/LeiMailSync.pm
index 32e17c65..b2986686 100644
--- a/lib/PublicInbox/LeiMailSync.pm
+++ b/lib/PublicInbox/LeiMailSync.pm
@@ -265,4 +265,36 @@ WHERE b.oidbin = ?
 	undef;
 }
 
+sub match_imap_url {
+	my ($self, $url, $all) = @_; # $all = [ $lms->folders ];
+	$all //= [ $self->folders ];
+	require PublicInbox::URIimap;
+	my $want = PublicInbox::URIimap->new($url)->canonical;
+	my ($s, $h, $mb) = ($want->scheme, $want->host, $want->mailbox);
+	my @uri = map { PublicInbox::URIimap->new($_)->canonical }
+		grep(m!\A\Q$s\E://.*?\Q$h\E\b.*?/\Q$mb\E\b!, @$all);
+	my @match;
+	for my $x (@uri) {
+		next if $x->mailbox ne $want->mailbox;
+		next if $x->host ne $want->host;
+		next if $x->port != $want->port;
+		my $x_uidval = $x->uidvalidity;
+		next if ($want->uidvalidity // $x_uidval) != $x_uidval;
+
+		# allow nothing in want to possibly match ";AUTH=ANONYMOUS"
+		if (defined($x->auth) && !defined($want->auth) &&
+				!defined($want->user)) {
+			push @match, $x;
+		# or maybe user was forgotten on CLI:
+		} elsif (defined($x->user) && !defined($want->user)) {
+			push @match, $x;
+		} elsif (($x->user//"\0") eq ($want->user//"\0")) {
+			push @match, $x;
+		}
+	}
+	return @match if wantarray;
+	scalar(@match) <= 1 ? $match[0] :
+			"E: `$url' is ambiguous:\n\t".join("\n\t", @match)."\n";
+}
+
 1;
diff --git a/t/lei-import-imap.t b/t/lei-import-imap.t
index d424ebb1..d3935c82 100644
--- a/t/lei-import-imap.t
+++ b/t/lei-import-imap.t
@@ -22,9 +22,15 @@ test_lei({ tmpdir => $tmpdir }, sub {
 	is_deeply(json_utf8->decode($lei_out), {}, 'no inspect stats, yet');
 
 	lei_ok('import', $url);
+	lei_ok('inspect', $url);
+	my $res = json_utf8->decode($lei_out);
+	is(scalar keys %$res, 1, 'got one key in inspect URL');
+	my $re = qr!\Aimap://;AUTH=ANONYMOUS\@\Q$host_port\E
+			/t\.v2\.0;UIDVALIDITY=\d+!x;
+	like((keys %$res)[0], qr/$re\z/, 'got expanded key');
+
 	lei_ok 'ls-mail-sync';
-	like($lei_out, qr!\Aimap://;AUTH=ANONYMOUS\@\Q$host_port\E
-			/t\.v2\.0;UIDVALIDITY=\d+\n\z!x, 'ls-mail-sync');
+	like($lei_out, qr!$re\n\z!, 'ls-mail-sync');
 	chomp(my $u = $lei_out);
 	lei_ok('import', $u, \'UIDVALIDITY match in URL');
 	$url = $u;

^ permalink raw reply	[flat|nested] 3+ messages in thread

* [PATCH 2/2] lei_mail_sync: reject IMAP URLs w/o UIDVALIDITY
  2021-05-23 21:36 [PATCH 0/2] lei IMAP usability stuff Eric Wong
  2021-05-23 21:36 ` [PATCH 1/2] lei inspect: use LeiMailSync->match_imap_url Eric Wong
@ 2021-05-23 21:36 ` Eric Wong
  1 sibling, 0 replies; 3+ messages in thread
From: Eric Wong @ 2021-05-23 21:36 UTC (permalink / raw)
  To: meta

It's inappropriate to store sync information without
UIDVALIDITY, so add an assertion to prevent it.
---
 lib/PublicInbox/LeiMailSync.pm | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/lib/PublicInbox/LeiMailSync.pm b/lib/PublicInbox/LeiMailSync.pm
index b2986686..63076fa1 100644
--- a/lib/PublicInbox/LeiMailSync.pm
+++ b/lib/PublicInbox/LeiMailSync.pm
@@ -7,6 +7,7 @@ use strict;
 use v5.10.1;
 use DBI;
 use PublicInbox::ContentHash qw(git_sha);
+use Carp ();
 
 sub dbh_new {
 	my ($self, $rw) = @_;
@@ -88,6 +89,10 @@ UPDATE folders SET loc = ? WHERE fid = ?
 EOM
 			return $fid;
 		}
+	} elsif ($rw && $folder =~ m!\Aimaps?://!i) {
+		require PublicInbox::URIimap;
+		PublicInbox::URIimap->new($folder)->uidvalidity //
+			Carp::croak("BUG: $folder has no UIDVALIDITY");
 	}
 	return unless $rw;
 

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2021-05-23 21:36 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-05-23 21:36 [PATCH 0/2] lei IMAP usability stuff Eric Wong
2021-05-23 21:36 ` [PATCH 1/2] lei inspect: use LeiMailSync->match_imap_url Eric Wong
2021-05-23 21:36 ` [PATCH 2/2] lei_mail_sync: reject IMAP URLs w/o UIDVALIDITY Eric Wong

user/dev discussion of public-inbox itself

This inbox may be cloned and mirrored by anyone:

	git clone --mirror https://public-inbox.org/meta
	git clone --mirror http://czquwvybam4bgbro.onion/meta
	git clone --mirror http://hjrcffqmbrq6wope.onion/meta
	git clone --mirror http://ou63pmih66umazou.onion/meta

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V1 meta meta/ https://public-inbox.org/meta \
		meta@public-inbox.org
	public-inbox-index meta

Example config snippet for mirrors.
Newsgroups are available over NNTP:
	nntp://news.public-inbox.org/inbox.comp.mail.public-inbox.meta
	nntp://7fh6tueqddpjyxjmgtdiueylzoqt6pt7hec3pukyptlmohoowvhde4yd.onion/inbox.comp.mail.public-inbox.meta
	nntp://ie5yzdi7fg72h7s4sdcztq5evakq23rdt33mfyfcddc5u3ndnw24ogqd.onion/inbox.comp.mail.public-inbox.meta
	nntp://4uok3hntl7oi7b4uf4rtfwefqeexfzil2w6kgk2jn5z2f764irre7byd.onion/inbox.comp.mail.public-inbox.meta
	nntp://news.gmane.io/gmane.mail.public-inbox.general
 note: .onion URLs require Tor: https://www.torproject.org/

code repositories for project(s) associated with this inbox:

	https://80x24.org/public-inbox.git

AGPL code for this site: git clone https://public-inbox.org/public-inbox.git