mutt: “index_format” daki koşullu tarih biçimi


15

Ben index_formatmutt için ayarlanmış aşağıdaki değeri var :

"%Z %{%Y %b %e  %H:%M} %?X?(%X)&   ? %-22.22F  %.100s %> %5c "

tarih biçiminde

2013 Dec 5

E-postanın ne kadar eski olduğuna bağlı olarak farklı tarih biçimlerine sahip olmanın mümkün olup olmadığını merak ediyordum. Bununla demek istediğim:

for less than 7 days:  today, yesterday, tuesday, monday
this year:             Dec 5
older than this year:  2013 Dec 5

Sanırım bu işlevselliği Thunderbird'de gördüm. Mutt içinde olması güzel olurdu

Yanıtlar:


16

Mutt'un (v1.5 +) "geliştirme" sürümünü kullanıyorsanız ve kesinlikle yapmanız gerekiyorsa, kılavuzda açıklandığı gibi harici bir filtre kullanma olasılığı vardır .

Öncelikle mesajın yaşına göre farklı şeyler çıktısı alabilen bir senaryoya ihtiyacınız var. Python'da bir örnek:

#!/usr/bin/env python
"""mutt format date

Prints different index_format strings for mutt according to a
messages age.

The single command line argument should be a unix timestamp
giving the message's date (%{}, etc. in Mutt).
"""

import sys
from datetime import datetime

INDEX_FORMAT = "%Z {} %?X?(%X)&   ? %-22.22F  %.100s %> %5c%"

def age_fmt(msg_date, now):
    # use iso date for messages of the previous year and before
    if msg_date.date().year < now.date().year:
        return '%[%Y-%m-%d]'

    # use "Month Day" for messages of this year
    if msg_date.date() < now.date():
        return '%10[%b %e]'

    # if a message appears to come from the future
    if msg_date > now:
        return '  b0rken'

    # use only the time for messages that arrived today
    return '%10[%H:%m]'

if __name__ == '__main__':
    msg_date = datetime.fromtimestamp(int(sys.argv[1]))
    now = datetime.now()
    print INDEX_FORMAT.format(age_fmt(msg_date, now))

Bunu mutt-fmt-datePATH'nizde bir yer olarak kaydedin.

Burada iki şey önemlidir:

  • Biçim dizgisinin bir yinelemesi Python tarafından {}döndürülen değeri içermelidir age_fmt().
  • Biçim dizesi %Mutt tarafından yorumlanacak şekilde sona ermelidir.

Sonra .muttrcaşağıdaki gibi kullanabilirsiniz :

set index_format="mutt-fmt-date %[%s] |"

Mutt sonra

  1. %[%s]Biçim dizgileri kurallarına göre yorumlar .
  2. mutt-fmt-dateargüman olarak 1. sonucuyla çağırın (çünkü |sonunda).
  3. komut dosyasından ne geri döndüğünü tekrar biçimlendirme dizgisi olarak yorumlar (çünkü %sonunda).

Dikkat : görüntülenecek olan her mesaj için komut dosyası yürütülür. Ortaya çıkan gecikme, bir posta kutusunda gezinirken oldukça fark edilebilir.

İşte C'de yeterince iyi performans gösteren bir sürüm:

#include <stdlib.h>
#include <stdio.h>
#include <time.h>

#define DAY (time_t)86400
#define YEAR (time_t)31556926

int main(int argc, const char *argv[]) {
    time_t current_time;
    time_t message_time;

    const char *old, *recent, *today;
    const char *format;

    current_time = time(NULL);

    if (argc!=6) {
        printf("Usage: %s old recent today format timestamp\n", argv[0]);
        return 2;
    }

    old = argv[1];
    recent = argv[2];
    today = argv[3];

    format = argv[4];

    message_time = atoi(argv[5]);

    if ((message_time/YEAR) < (current_time/YEAR)) {
        printf(format, old);
    } else if ((message_time/DAY) < (current_time/DAY)) {
        printf(format, recent);
    } else {
        printf(format, today);
    }

    return 0;
}

Bu muttrc hattı ile birlikte gider:

set index_format='mfdate "%[%d.%m.%y]" "%8[%e. %b]" "%8[%H:%m]" "%Z %%s %-20.20L %?y?[%-5.5y]&       ? %?M?+& ?%s%%" "%[%s]" |'

Henüz hata ayıklamak için zamanım olmadı, ancak bu çözüm ve% işareti içeren konularla ilgili bir sorun var gibi görünüyor. Yamalar takdir edilecektir!

1
Bir ödül yarattım. Hatayı nasıl düzeltebileceğiniz hakkında bir fikriniz var mı?
Martin Vegter

7

Ne yazık ki, Mutt'un mevcut sürümleriyle bu mümkün görünmüyor.

$index_formatçeşitli mesaj meta verilerinden çizim yaparak belirli bir format belirteçleri kümesini destekler. Mutt kılavuzunda açıklanmıştır (ya da bunun için "kararlı" sürümün belgeleri ) ve tablodan görebileceğiniz gibi, koşullu olan sadece birkaç format belirteci vardır. Bunlar %M, %yve %Y; % M gizli olan mesaj sayısını eğer Y, X-etiket başlık olduğu iplik daraltılmış ve% y ve% halinde mevcut.

İleti tarih ve saatinin gerçek biçimlendirmesi, strftime(3)koşullu biçimlendirmeyi hiç desteklemeyen tarafından yapılır .

Belki bir yapmak mümkün çirkin sürekli mesaj files' yeniden yazarak geçici çözümü Date:başlıkları, ama en azından bunu yapmak istemem. Ancak, aklıma gelen en az kötü olasılık.

Aklıma gelen tek gerçek çözüm ya Mutt'ta böyle bir destek uygulamak (bu kesinlikle Thunderbird'ün yaptığı gibi) ya da strftimekoşullu biçimlendirmeyi destekleyen ve LD_PRELOAD ya da benzer bir mekanizma kullanarak enjekte eden bir yedek yazmak olacaktır . Ancak ikincisi, Mutt'ta sadece mesaj dizini ile ilgili değil, iş saatinde geçen tüm tarih ve saat görüntüsünü etkileyecektir .


2
Sürüm 1.5+ kullanıyorsanız (ki kesinlikle yapmanız gerekir), bir yolu var. Yine de tarih başlıklarını yeniden yazmak

@hop FWIW, cevabınız benim oyumu aldı.
CVn

4

Bazı nedenlerden dolayı mutt'un yeni sürümleri (1.7 bu sorunu gösterdi) atoi'nin dizeyi int'e dönüştürmesini engelleyen '14' ve '32' karakterleriyle tarih dizesine önek ekler. Satırı şu şekilde değiştirme

message_time = atoi(2+argv[7]);

Muhtemelen aptalca bir çözüm, ama benim için çalışıyor.


4

@Marcus 'c sürümü biraz düzenlendi ( %konu konusunda hala bir çözüm yok ):

// -*- coding:utf-8-unix; mode:c; -*-
/*
    Sets mutt index date based on mail age.

build:
    gcc mutt-index-date-formatter.c -o mutt-index-format
use this line in .muttrc:
    set index_format = 'mutt-index-format "%9[%d.%m.%y]" "%9[%e.%b]" "%8[%a %H:%m]" "%[%H:%m]" "%3C [%Z] %?X?%2X& -? %%s %-20.20L %?M?+%-2M&   ? %s %> [%4c]asladfg" "%[%s]" |'*/
// ////////////////////////////////////////////////////////////////

#include <stdlib.h>
#include <stdio.h>
#include <time.h>

#define DAY (time_t)86400
#define WEEK (time_t)604800
#define YEAR (time_t)31556926

int main(int argc, const char *argv[]) {
    time_t current_time;
    time_t message_time;
    struct tm *ltime;
    unsigned int todays_seconds=0;
    unsigned int seconds_this_morning=0;

    const char *last_year, *this_year, *last_months, *last_week, *today;
    const char *format;
    char *concat_str;

    current_time = time(NULL);
    ltime = localtime(&current_time);
    todays_seconds = ltime->tm_hour*3600 + ltime->tm_min*60 + ltime->tm_sec;
    seconds_this_morning = current_time - todays_seconds;  // unix time @ 00:00

    if (argc != 7) {
        printf("Usage: %s last_year this_year last_week today format timestamp\n", argv[0]);
        return 2;
    }

    last_year    = argv[1];
    this_year    = argv[2];
    last_week    = argv[3];
    today        = argv[4];

    format       = argv[5];

    message_time = atoi(2 + argv[6]);

    if (message_time >= seconds_this_morning) {
        asprintf(&concat_str, "    %s", today);
        printf(format, concat_str);
    } else if (message_time >= seconds_this_morning - DAY) {
        asprintf(&concat_str, "ydy %s", today);
        printf(format, concat_str);
    } else if (message_time > seconds_this_morning - WEEK) {
        printf(format, last_week);
    } else if (message_time/YEAR < current_time/YEAR) {
        printf(format, last_year);
    } else {
        printf(format, this_year);
    }

    return 0;
}

Bu biçimler şu şekilde tarihlenir (tüm zamanlar 24 saat biçimindedir):

  • 02:04 bugünün postası için
  • ydy 02:04 dünkü posta için
  • Thu 02:04 son 7 gün posta için
  • 27.Mar cari yıl postası için
  • 13.12.16 önceki yılların postası için

Bu örnekteki tam dizin biçimi: #no [flags] #no_of_attachments date sender subject msg_size


3

Bazı değişiklikler yaptı, ancak "konudaki%" sorununu çözmedi

#include <stdlib.h>
#include <stdio.h>
#include <time.h>

#define DAY (time_t)86400
#define WEEK (time_t)604800
#define MONTH (time_t)2678400
#define YEAR (time_t)31556926

/*I use this line in .muttrc: 
 * set index_format        = '/home/marcus/.mutt/mfdate "%9[%d.%m.%y]" "%9[%e.%b]" " [%6[%e.%b]]" "%8[%a %H:%m]" "    %[%H:%m]" "%Z %%s %?X?%2X&  ? %-20.20L %?M?+%-2M&   ? %.86s %> [%4c]asladfg" "%[%s]" |'*/
int main(int argc, const char *argv[]) {
    time_t current_time;
    time_t message_time;
    struct tm *ltime;
    unsigned int todays_seconds=0;
    unsigned int seconds_this_morning=0;


    const char *last_year, *this_year, *last_months, *last_week, *today;
    const char *format;

    current_time = time(NULL);
    ltime = localtime(&current_time);
    todays_seconds = ltime->tm_hour*3600 + ltime->tm_min*60 + ltime->tm_sec;
    seconds_this_morning = current_time - todays_seconds;

    if (argc!=8) {
        printf("Usage: %s last_year this_year today format timestamp\n", argv[0]);
        return 2;
    }

    last_year    = argv[1];
    this_year    = argv[2];
    last_months  = argv[3];
    last_week    = argv[4];
    today        = argv[5];

    format       = argv[6];

    message_time = atoi(argv[7]);

    /*
     *if ((message_time+YEAR) < current_time) {
     *    printf(format, last_year);
     *} else if ((message_time+MONTH) < current_time) {
     *    printf(format, this_year);
     *} else if ((message_time+WEEK) < current_time) {
     *    printf(format, last_months);
     *} else if ((message_time+DAY) < current_time) {
     *    printf(format, last_week);
     *} else {
     *    printf(format, today);
     *}
     */

    if ((message_time/YEAR) < (current_time/YEAR)) {
        printf(format, last_year);
    } else if ((message_time/MONTH) < (current_time/MONTH)) {
        printf(format, this_year);
    } else if ((message_time + WEEK) < current_time) {
    /*} else if ((message_time/DAY) < (current_time/DAY)) {*/
        printf(format, last_months);
    /*
     *} else if ((message_time+DAY) < current_time) {
     *    printf(format, last_week);
     */
    } else if ((message_time ) < seconds_this_morning) {
        printf(format, last_week);
    } else {
        printf(format, today);
    }

    return 0;
}

Yaptığınız değişiklikleri ve bunların arkasındaki nedenleri özetlemeniz iyi olur.
zagrimsan

0

Bu index_formatdeğişken

set index_format='mfdate "%[%s]" "%4C %Z %[!%b %d %Y] %-17.17F (%3l) %s" |'

ile birlikte bu değiştirilmiş kullanıcı hop tarafından mfdate.csunulan cevap :

#include <stdlib.h>
#include <stdio.h>
#include <time.h>

#define DAY (time_t)86400
#define YEAR (time_t)31556926

int main(int argc, const char *argv[]) {
  time_t current_time;
  time_t message_time;

  const char *old = "old";
  char *recent = "recent";
  char *today = "today";
  const char *format;

  current_time = time(NULL);

  if (argc != 3) {
    printf("Usage: %s format\n", argv[0]);
    return EXIT_FAILURE;
  }

  format = argv[2];

  message_time = atoi(argv[1]);

  if ((message_time/YEAR) < (current_time/YEAR)) {
    printf("%s,%s", old, format);
  } else if ((message_time/DAY) < (current_time/DAY)) {
    printf("%s,%s", recent, format);
  } else {
    printf("%s,%s", today, format);
  }

  return EXIT_SUCCESS;
}

benim için doğru çalışıyor mutt 1.6.1ve gördüğünüz gibi %konudaki sorunla ilgili herhangi bir sorun yok , eğer gerçek sorun buysa:resim açıklamasını buraya girin

Bu ilk "sadece çalışıyor" versiyonu çünkü orijinal sorunuza daha yakından baktıktan sonra, bunun ne istediğinizden emin değilim. Ancak, bu takdirde olduğunu bana bildirin istediğini ve daha iyi yapmak için nasıl düşüneceğim.

DÜZENLE :

Ayrıca tercih ettiğiniz ile çalışabilir index_format:

set index_format='mfdate "%[%s]" "%%Z %%{%%Y %%b %%e  %%H:%%M} %%?X?(%%X)&   ? %%-22.22F  %%.100s %%> %%5c" |'

mfdate.c:

#include <stdlib.h>
#include <stdio.h>
#include <time.h>

#define DAY (time_t)86400
#define YEAR (time_t)31556926

int main(int argc, const char *argv[]) {
  time_t current_time;
  time_t message_time;

  const char *old = "old";
  char *recent = "recent";
  char *today = "today";
  const char *format;

  current_time = time(NULL);

  if (argc != 3) {
    printf("Usage: %s format\n", argv[0]);
    return EXIT_FAILURE;
  }

  format = argv[2];

  message_time = atoi(argv[1]);

  if ((message_time/YEAR) < (current_time/YEAR)) {
    printf("%s,%s%%", old, format);
  } else if ((message_time/DAY) < (current_time/DAY)) {
    printf("%s,%s%%", recent, format);
  } else {
    printf("%s,%s%%", today, format);
  }

  return 0;
}

resim açıklamasını buraya girin

DÜZENLE :

Nasıl çalıştığını açıklayayım:

mfdate2 argüman alır:

"%[%s]"

ve:

"%%Z %%{%%Y %%b %%e  %%H:%%M} %%?X?(%%X)&   ? %%-22.22F  %%.100s %%> %%5c"

İlk argüman yalnızca aşağıdaki belgelerde time of the messageaçıklandığı gibidir :index_format.muttrc

# %[fmt]  the date and time of the message is converted to the local
#         time zone, and ``fmt'' is expanded by the library function
#         ``strftime''; a leading bang disables locales

Bu durumda fmt, yerine açıklandığı %sgibi %saraçlarla değiştirilir . İlk argüman ne kadar eski mesajdır ve hangi etiketi hesaplamak için kullanılır: , ya da sahip olmalıdır.The number of seconds since the Epochman strftimeoldrecenttoday

İkinci argüman değişkenin geri kalan kısmıdır index_format . Sadece mfdatebaskı için kullanılır, ancak mutt kılavuzunda dediği gibi bir ekstra %eklenir :printf

Döndürülen dize görüntüleme için kullanılacaktır. Döndürülen dize% ile biterse, ikinci kez biçimlendiriciden geçirilir.

%Burada her şey iki katına çıkar, çünkü biz %tarafından yapılan ikinci biçimlendirmeye değişmez bir şekilde geçmek istiyoruz mutt.


Neden inişli çıkışlı? Bu cevapla ilgili bir sorun mu var?
Arkadiusz Drabczyk
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.