diff options
| -rwxr-xr-x | backup-gnucash.sh | 2 | ||||
| -rwxr-xr-x | dim-screen.sh | 44 | ||||
| -rwxr-xr-x | git-add-jesterpm-remote | 8 | ||||
| -rwxr-xr-x | imap-pass | 2 | ||||
| -rwxr-xr-x | khal-accept | 6 | ||||
| -rwxr-xr-x | ledger-convert-becu | 20 | ||||
| -rwxr-xr-x | ledger-convert-discover | 20 | ||||
| -rwxr-xr-x | ledger-tax-report | 276 | ||||
| -rwxr-xr-x | lock | 84 | ||||
| -rwxr-xr-x | mailto-mutt | 101 | ||||
| -rwxr-xr-x | morse-runner | 3 | ||||
| -rwxr-xr-x | mutt-display-filter.sh | 3 | ||||
| -rwxr-xr-x | mutt-ical.py | 14 | ||||
| -rwxr-xr-x | play-minecraft | 6 | ||||
| -rwxr-xr-x | view_attachment | 129 |
15 files changed, 694 insertions, 24 deletions
diff --git a/backup-gnucash.sh b/backup-gnucash.sh index a62199d..fe10568 100755 --- a/backup-gnucash.sh +++ b/backup-gnucash.sh @@ -1,6 +1,6 @@ #!/bin/sh -BACKUP=$HOME/documents/finances/gnucash-backup +BACKUP=$HOME/sync/gnucash-backup MASTER=$HOME/gnucash-master TEST_FILE=$MASTER/2016.gnucash diff --git a/dim-screen.sh b/dim-screen.sh new file mode 100755 index 0000000..9958917 --- /dev/null +++ b/dim-screen.sh @@ -0,0 +1,44 @@ +#!/bin/bash -x + +# Example notifier script -- lowers screen brightness, then waits to be killed +# and restores previous brightness on exit. + +## CONFIGURATION ############################################################## + +# Brightness will be lowered to this value. +min_brightness=500 + +# If your video driver works with xbacklight, set -time and -steps for fading +# to $min_brightness here. Setting steps to 1 disables fading. +fade_steps=20 + +# Time to sleep (in seconds) between increments when using sysfs. If unset or +# empty, fading is disabled. +fade_step_time=0.05 + +############################################################################### + +get_brightness() { + brightnessctl get +} + +set_brightness() { + brightnessctl set $1 +} + +fade_brightness() { + local level + local value=$(get_brightness) + local decrement=$((($value - $1) / $fade_steps)) + for level in $(eval echo {$fade_steps..1}); do + local value=$(($value - $decrement)) + set_brightness $value + sleep $fade_step_time + done +} + +trap 'exit 0' TERM INT +trap "set_brightness $(get_brightness); kill %%" EXIT +fade_brightness $min_brightness +sleep 2147483647 & +wait diff --git a/git-add-jesterpm-remote b/git-add-jesterpm-remote new file mode 100755 index 0000000..37651d4 --- /dev/null +++ b/git-add-jesterpm-remote @@ -0,0 +1,8 @@ +#!/bin/sh + +NAME=${1:-$(basename $PWD)} +REMOTE=${2:-origin} + +ssh git.jesterpm.net "git init --bare git/${NAME}.git" +git remote add $REMOTE git.jesterpm.net:git/${NAME}.git +git push -u $REMOTE --all @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 import argparse import keyring diff --git a/khal-accept b/khal-accept new file mode 100755 index 0000000..15bba55 --- /dev/null +++ b/khal-accept @@ -0,0 +1,6 @@ +#!/bin/sh + +FILE=$(mktemp invite-XXXX.ics) +cat - > $FILE +khal import $FILE +rm $FILE diff --git a/ledger-convert-becu b/ledger-convert-becu new file mode 100755 index 0000000..224fb22 --- /dev/null +++ b/ledger-convert-becu @@ -0,0 +1,20 @@ +#!/bin/sh + +ACCOUNT=$1 +FILE=$2 + +# Incoming header is +# "Date","No.","Description","Debit","Credit" +# +# Ledger columns are +# transid,date,payee,note,debit,credit,,code, + +sed '1 s/.*/date,code,payee,debit,credit/' $FILE | sed 's/"-/"/' |tr -d \" > ${FILE}.ledger +ledger convert ${FILE}.ledger \ + --input-date-format '%m/%d/%Y' \ + --account "Assets:Current Assets:$ACCOUNT" \ + --auto-match \ + --rich-data --invert + + + diff --git a/ledger-convert-discover b/ledger-convert-discover new file mode 100755 index 0000000..046aa65 --- /dev/null +++ b/ledger-convert-discover @@ -0,0 +1,20 @@ +#!/bin/sh + +FILE=$1 + +# Incoming header is +# "Date","No.","Description","Debit","Credit" +# Trans. Date,Post Date,Description,Amount,Category +# +# Ledger columns are +# transid,date,payee,note,debit,credit,,code, + +sed '1 s/.*/date,,payee,amount,/' $FILE | tr -d "\r" > ${FILE}.ledger +ledger convert ${FILE}.ledger \ + --input-date-format '%m/%d/%Y' \ + --account "Liabilities:Discover" \ + --auto-match \ + --rich-data + + + diff --git a/ledger-tax-report b/ledger-tax-report new file mode 100755 index 0000000..de91f29 --- /dev/null +++ b/ledger-tax-report @@ -0,0 +1,276 @@ +#!/usr/bin/env python3 + +import re +import subprocess +import sys + +if len(sys.argv) == 2: + year = sys.argv[1] +else: + year = '2023' + +def ledger_amount(query): + p = subprocess.run("ledger -p '%s' -n -J --yearly reg %s" % (year, query,), + shell=True, stdout=subprocess.PIPE, text=True) + parts = p.stdout.split(' ') + if len(parts) == 2: + return float(parts[1]) + else: + return 0.0 + +def parse_tax_table(input): + filing_status = 2 # Married/Jointly + table = [] + delta = 0 + prev_max_tax = 0 + for line in input.split("\n"): + if not line: + continue + cols = line.split("\t") + rate = float(cols[0].strip(' %')) / 100.0 + brk = re.sub('[$,]', '', cols[filing_status]).split(' ') + lower = brk[0] + upper = brk[2] + delta + if upper == 'more': + table.append((float(lower), None, rate, delta)) + else: + delta += rate * float(lower) - prev_max_tax + prev_max_tax = float(upper) * rate + table.append((float(lower), float(upper), rate, delta)) + return table + + +income_tax_table = {} + +# c&p from https://taxfoundation.org/2022-tax-brackets/ +income_tax_table['2022'] = parse_tax_table(''' +10% $0 to $10,275 $0 to $20,550 $0 to $14,650 +12% $10,275 to $41,775 $20,550 to $83,550 $14,650 to $55,900 +22% $41,775 to $89,075 $83,550 to $178,150 $55,900 to $89,050 +24% $89,075 to $170,050 $178,150 to $340,100 $89,050 to $170,050 +32% $170,050 to $215,950 $340,100 to $431,900 $170,050 to $215,950 +35% $215,950 to $539,900 $431,900 to $647,850 $215,950 to $539,900 +37% $539,900 or more $647,850 or more $539,900 or more +''') + +# c&p from https://taxfoundation.org/2023-tax-brackets/ +income_tax_table['2023'] = parse_tax_table(''' +10% $0 to $11,000 $0 to $22,000 $0 to $15,700 +12% $11,000 to $44,725 $22,000 to $89,450 $15,700 to $59,850 +22% $44,725 to $95,375 $89,450 to $190,750 $59,850 to $95,350 +24% $95,375 to $182,100 $190,750 to $364,200 $95,350 to $182,100 +32% $182,100 to $231,250 $364,200 to $462,500 $182,100 to $231,250 +35% $231,250 to $578,125 $462,500 to $693,750 $231,250 to $578,100 +37% $578,125 or more $693,750 or more $578,100 or more +''') + +def compute_income_tax(income): + for (lower, upper, rate, sub) in income_tax_table[year]: + if income > lower and (upper is None or income <= upper): + return round(income * rate - sub) + raise Exception("Failed to compute tax") + +def compute_tax_worksheet(taxable_income, qualified_dividends, schedule_d): + line = {} + line['1'] = taxable_income + line['2'] = qualified_dividends + line['3'] = max(0, min(schedule_d['15'], schedule_d['16'])) + line['4'] = line['2'] + line['3'] + line['5'] = max(0, taxable_income - line['4']) + line['6'] = 83350.00 # TODO Tax table (this number from 2022) + line['7'] = min(taxable_income, line['6']) + line['8'] = min(line['5'], line['7']) + line['9'] = line['7'] - line['8'] # 0% tax amount + line['10'] = min(taxable_income, line['4']) + line['11'] = line['9'] + line['12'] = line['10'] - line['11'] + line['13'] = 517200.00 # TODO Tax table (this number from 2022) + line['14'] = min(taxable_income, line['13']) + line['15'] = line['5'] + line['9'] + line['16'] = max(0, line['14'] - line['15']) + line['17'] = min(line['12'], line['16']) + line['18'] = line['17'] * 0.15 + line['19'] = line['9'] + line['17'] + line['20'] = line['10'] - line['19'] + line['21'] = line['20'] * 0.20 + line['22'] = compute_income_tax(line['5']) + line['23'] = line['18'] + line['21'] + line['22'] + line['24'] = compute_income_tax(taxable_income) + line['25'] = min(line['23'], line['24']) + return line + +def compute_schedule_d(net_st, net_lt): + line = {} + line['7'] = net_st + line['15'] = net_lt + line['16'] = line['7'] + line['15'] + + # N.B. this deviates from the instructions + # For simplicity, Form 1040 will always get line 7 from schedule D line 21. + line['21'] = line['16'] + + if line['16'] > 0: + if line['15'] > 0: + line['17'] = 'Yes' + line['18'] = 0.00 # TODO: 28% Rate Gain Worksheet + line['19'] = 0.00 # TODO: Section 1250 Worksheet + if line['18'] == 0.00 and line['19'] == 0.00: + line['20'] = 'Yes' + return line + else: + line['20'] = 'No' + raise Exception("TODO: Implement Schedule D worksheet") + else: + line['17'] = 'No' + # Goto line 22 + elif line['16'] < 0: + # Goto Line 21 (and 22) + line['21'] = max(-3000.00, line['16']) + + # Line 22 - Do you have qualified dividends? + + return line + +def compute_deduction(deductions, limited): + itemized = deductions + itemized += min(10000, limited) + standard = 25900 # TODO Tax table + return max(itemized, standard) + +def credit_limit_worksheet_a(line18): + line = {} + line['1'] = line18 + line['2'] = 0.00 # TODO: Schedule 3 + line['3'] = line['1'] - line['2'] + line['4'] = 0 # TODO: Credit Limit Worksheet B + line['5'] = line['3'] - line['4'] + return line + +# Schedule 8812 +def compute_child_tax_credit(agi, dependants, line18): + line = {} + line['1'] = agi + line['3'] = line['1'] + line['4'] = dependants + line['5'] = line['4'] * 2000.00 + line['6'] = 0 + line['7'] = line['6'] * 500.00 + line['8'] = line['5'] + line['7'] + line['9'] = 400000.00 # Married, filing jointly + line['10'] = max(0, round((line['3'] - line['9'])/1000) * 1000) + line['11'] = line['10'] * 0.05 + if line['8'] > line['11']: + line['12'] = line['8'] - line['11'] + else: + line['14'] = 0 + line['27'] = 0 + return line + line['13'] = credit_limit_worksheet_a(line18)['5'] + line['14'] = min(line['12'], line['13']) + return line + + + + +print("Tax report for %s" % (year)) +print("-------------------") + +################################# +# Gather ledger values + +# Income +income = 0 - ledger_amount('tag EarnedIncome') +taxable_interest = 0 - ledger_amount('"Interest and not HSA"') +qualified_dividends = 0 - ledger_amount('tag QualifiedDividends') +ordinary_dividends = 0 - ledger_amount('tag OrdinaryDividends') +net_st = 0 - ledger_amount('tag ShortTermGains') +net_lt = 0 - ledger_amount('tag LongTermGains') + +# Expenses +total_payments = ledger_amount('tag TaxesPaid') +deductions = ledger_amount('tag ^TaxDeductible$') +deductions_limited = ledger_amount('tag ^TaxDeductibleLimited$') + +# Other +dependants = 2 + + +############################ +# Compute taxes + + +schedule_d = compute_schedule_d(net_st, net_lt) + +line = {} + +# Income +line['1z'] = income +line['2b'] = taxable_interest +line['3a'] = qualified_dividends +line['3b'] = ordinary_dividends +line['4b'] = 0.00 # TODO: IRA Distribution +line['5b'] = 0.00 # TODO: Pension +line['6b'] = 0.00 # TODO: Social security +line['7'] = schedule_d['21'] +line['8'] = 0.00 # TODO: Schedule 1 +line['9'] = line['1z'] + line['2b'] + line['3b'] + line['4b'] + \ + line['5b'] + line['6b'] + line['7'] + line['8'] + +line['10'] = 0.00 # TODO Schedule 1 (line 26) +line['11'] = line['9'] - line['10'] + +line['12'] = compute_deduction(deductions, deductions_limited) +line['13'] = 0.00 # TODO: Form 8995 +line['14'] = line['12'] + line['13'] +line['15'] = max(0, line['11'] - line['14']) + +# Tax and Credits +tax_worksheet = compute_tax_worksheet(line['15'], line['3a'], schedule_d) +line['16'] = tax_worksheet['25'] +line['17'] = 0.00 # TODO: Schedule 2 (line 3) +line['18'] = line['16'] + line['17'] +line['19'] = compute_child_tax_credit(line['11'], dependants, line['18'])['14'] +line['20'] = 0.00 # TODO: Schedule 3 (line 8) +line['21'] = line['19'] + line['20'] +line['22'] = max(0, line['18'] - line['21']) +line['23'] = 0.00 # TODO Schedule 2 (line 21) +line['24'] = line['22'] + line['23'] + +# Payments +line['33'] = total_payments + +# Refund +line['34'] = max(0, line['33'] - line['24']) + +# Amount You Owe +line['37'] = max(0, line['24'] - line['33']) +# TODO Penalty + + +#################### + +print(" 1z. Total income ${:>12,.0f}".format(line['1z'])) +print(" 2b. Taxable interest ${:>12,.0f}".format(line['2b'])) +print(" 3b. Ordinary dividends ${:>12,.0f}".format(line['3b'])) +print(" 7. Capital gain (loss) ${:>12,.0f}".format(line['7'])) +print(" 8. Other income ${:>12,.0f}".format(line['8'])) +print(" 9. Total income ${:>12,.0f}".format(line['9'])) +print(" 10. Adjustments ${:>12,.0f}".format(line['10'])) +print(" 11. AGI ${:>12,.0f}".format(line['11'])) +print() + +print(" 12. Deductions ${:>12,.0f}".format(line['12'])) +print(" 13. Business deduction ${:>12,.0f}".format(line['13'])) +print(" 15. Taxable income ${:>12,.0f}".format(line['15'])) +print() + +print(" 16. Tax ${:>12,.0f}".format(line['16'])) +print(" 16. Total tax ${:>12,.0f}".format(line['24'])) +print(" 33. Total payments ${:>12,.0f}".format(line['33'])) + +if line['34'] > 0: + print(" 34. Tax refund ${:>12,.0f}".format(line['34'])) +else: + print(" 37. Taxes owed ${:>12,.0f}".format(line['37'])) + @@ -1,20 +1,74 @@ -#!/bin/sh +#!/bin/bash -# Pause music -if pgrep xmms2 &> /dev/null; then - xmms2 pause -fi +# Example locker script -- demonstrates how to use the --transfer-sleep-lock +# option with i3lock's forking mode to delay sleep until the screen is locked. -# Set pidgin away. -if pgrep pidgin &> /dev/null; then - currentStatusMessage="$(purple-remote 'getstatusmessage')" - currentStatus="$(purple-remote 'getstatus')" - purple-remote 'setstatus?status=away&message=Away' -fi +## Prepare image + +SCREEN_RESOLUTION="$(xdpyinfo | grep dimensions | cut -d' ' -f7)" +BGCOLOR="0,0,0" +convert "$HOME/photos/wallpapers/morgan-flag.png" -gravity Northwest -background $BGCOLOR -extent "$SCREEN_RESOLUTION" $HOME/photos/wallpapers/.lockscreen.png + + +## CONFIGURATION ############################################################## + +# Options to pass to i3lock +i3lock_options="-ti $HOME/photos/wallpapers/.lockscreen.png" + + +# Run before starting the locker +pre_lock() { + # Pause music + #if pgrep xmms2 &> /dev/null; then + #xmms2 pause + #fi + + # Set pidgin away. + if pgrep pidgin &> /dev/null; then + currentStatusMessage="$(purple-remote 'getstatusmessage')" + currentStatus="$(purple-remote 'getstatus')" + purple-remote 'setstatus?status=away&message=Away' + fi -#i3lock -n -i $HOME/.wallpapers/lock.png --color=0e0e0e -u -m -xscreensaver-command -lock + return +} -if pgrep pidgin &> /dev/null; then - purple-remote 'setstatus?status='"$currentStatus"'&message='"$currentStatusMessage" +# Run after the locker exits +post_lock() { + if pgrep pidgin &> /dev/null; then + purple-remote 'setstatus?status='"$currentStatus"'&message='"$currentStatusMessage" + fi + + return +} + +############################################################################### + +pre_lock + +# We set a trap to kill the locker if we get killed, then start the locker and +# wait for it to exit. The waiting is not that straightforward when the locker +# forks, so we use this polling only if we have a sleep lock to deal with. +if [[ -e /dev/fd/${XSS_SLEEP_LOCK_FD:--1} ]]; then + kill_i3lock() { + pkill -xu $EUID "$@" i3lock + } + + trap kill_i3lock TERM INT + + # we have to make sure the locker does not inherit a copy of the lock fd + i3lock $i3lock_options {XSS_SLEEP_LOCK_FD}<&- + + # now close our fd (only remaining copy) to indicate we're ready to sleep + exec {XSS_SLEEP_LOCK_FD}<&- + + while kill_i3lock -0; do + sleep 0.5 + done +else + trap 'kill %%' TERM INT + i3lock -n $i3lock_options & + wait fi + +post_lock diff --git a/mailto-mutt b/mailto-mutt new file mode 100755 index 0000000..ed512ee --- /dev/null +++ b/mailto-mutt @@ -0,0 +1,101 @@ +#!/bin/sh +exec $TERMINAL -e mutt "$@" +#!/usr/bin/env perl + +# mutt-mailto - use Mutt on mailto URIs, e.g. with browsers like Firefox +# Copyright 2005-2020 Vincent Lefevre <vincent@vinc17.net>. + +# To use this script with Firefox, at least under GNU/Linux, open the +# Preferences -> Applications dialog, and for "mailto" content type, +# choose "Use other..." and select this script. +# Note: after that, the mimeTypes.rdf file in the Firefox profile +# should contain something like: +# <RDF:Description RDF:about="urn:handler:local:/path/to/mutt-mailto" +# NC:prettyName="mutt-mailto" NC:path="/path/to/mutt-mailto"/> +# <RDF:Description RDF:about="urn:scheme:externalApplication:mailto" +# NC:prettyName="mutt-mailto" NC:path="/path/to/mutt-mailto"/> + +# 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., +# 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. + +# History: +# 2005-01-14 Initial version. +# 2006-02-17 If not in a terminal, use emacs instead of uxterm. +# 2009-02-18 If not in a terminal, force UTF-8. +# 2009-05-22 If provided body, use /dev/fd or File::Temp instead of /proc. +# 2020-05-06 When forcing UTF-8: replaced "en_US.UTF-8" by "C.UTF-8". + +use strict; +use Fcntl qw/F_SETFD/; +use IO::Handle; +use URI; + +my ($proc) = '$Id: mutt-mailto 127329 2020-05-06 13:55:16Z vinc17/zira $' + =~ /^.Id: (\S+) / or die; + +$ARGV[0] =~ /^mailto:/ or die "Usage: $proc <mailtoURI>\n"; + +my $u = URI->new($ARGV[0]); +my %headers = $u->headers; +my $to = $u->to; +my @cmd = -t STDIN ? qw/mutt/ : + qw/%ENV{'TERMINAL'} -e mutt -e autoedit=yes/; +# qw/env LC_CTYPE=C.UTF-8 LC_CHARMAP=UTF-8 emacs -l emacs-mutt.el/; +# (qw/uxterm +sb -sl 0 -n mutt-mailto -T/, "Mutt $to", qw/-e mutt/); +my $body; +while (my ($k,$v) = each %headers) + { + lc($k) eq 'bcc' and push @cmd, '-b', $v; + lc($k) eq 'cc' and push @cmd, '-c', $v; + lc($k) eq 'subject' and push @cmd, '-s', $v; + lc($k) eq 'body' and $body = $v; + } + +if ($body ne '') + { + chomp $body; + open TMP, '>', undef + or die "$proc: can't create temporary file\n$!\n"; + autoflush TMP 1; + print TMP "$body\n" + or die "$proc: can't print to temporary file\n$!\n"; + fcntl(TMP, F_SETFD, 0) + or die "$proc: can't clear close-on-exec flag on temporary file\n$!\n"; + my $fname = "/dev/fd/".fileno(TMP); + open FILE, $fname + or die "$proc: can't reopen temporary file\n$!\n"; + my $empty = <FILE> eq ''; + close FILE; + my $tmp; + if ($empty) # occurs under Mac OS X Tiger + { + # Fallback to File::Temp (the temporary file is visible and + # will not be destroyed if mutt-mailto is killed). + require File::Temp; + $tmp = File::Temp->new(); + $fname = $tmp->filename; + open TMP, '>', $fname + or die "$proc: can't create temporary file\n$!\n"; + print TMP "$body\n" + or die "$proc: can't print to temporary file\n$!\n"; + } + system @cmd, '-i', $fname, $to; + close TMP or die "$proc: can't close temporary file\n$!\n"; + } +else + { exec @cmd, $to } + +# Test on: +# mailto:a1@x?To=a2@x&Cc=a3@x&Bcc=a4@x&Subject=mailto%20test +# mailto:a1@x?To=a2@x&Cc=a3@x&Bcc=a4@x&Subject=mailto%20test&body=The%20body. diff --git a/morse-runner b/morse-runner new file mode 100755 index 0000000..e3efb26 --- /dev/null +++ b/morse-runner @@ -0,0 +1,3 @@ +#!/bin/sh + +WINEPREFIX="$HOME/.wine-rufzxp" wine .wine-rufzxp/drive_c/Program\ Files/Afreet/MorseRunner/MorseRunner.exe diff --git a/mutt-display-filter.sh b/mutt-display-filter.sh index 7653d5d..c91612e 100755 --- a/mutt-display-filter.sh +++ b/mutt-display-filter.sh @@ -11,5 +11,6 @@ else fi # Rewrite date to local time -echo "${MESSAGE}" | sed -r "s/^Date:\\s*(([F-Wa-u]{3},\\s*)?[[:digit:]]{1,2}\\s+[A-Sa-y]{3}\\s+[[:digit:]]{4}\\s+[[:digit:]]{1,2}:[[:digit:]]{1,2}(:[[:digit:]]{1,2})?\\s+[+-][[:digit:]]{4})/date +'Date: %a, %d %b %Y %H:%M:%S %z' -d '\\1'/e" +echo "${MESSAGE}" +#| sed -r "s/^Date:\\s*(([F-Wa-u]{3},\\s*)?[[:digit:]]{1,2}\\s+[A-Sa-y]{3}\\s+[[:digit:]]{4}\\s+[[:digit:]]{1,2}:[[:digit:]]{1,2}(:[[:digit:]]{1,2})?\\s+[+-][[:digit:]]{4})/date +'Date: %a, %d %b %Y %H:%M:%S %z' -d '\\1'/e" diff --git a/mutt-ical.py b/mutt-ical.py index 164fb8d..a7da13a 100755 --- a/mutt-ical.py +++ b/mutt-ical.py @@ -158,7 +158,7 @@ def organizer(ical): raise("no organizer in event") if __name__=="__main__": - email_address = None + email_address = [] accept_decline = 'ACCEPTED' opts, args=getopt(sys.argv[1:],"e:aidtD") @@ -173,7 +173,7 @@ if __name__=="__main__": if opt == '-D': sys.exit(0) if opt == '-e': - email_address = arg + email_address.append(arg) if opt == '-i': accept_decline = get_accept_decline() if opt == '-a': @@ -195,11 +195,11 @@ if __name__=="__main__": flag = 1 for attendee in attendees: if hasattr(attendee,'EMAIL_param'): - if attendee.EMAIL_param == email_address: + if attendee.EMAIL_param in email_address: ans.vevent.attendee_list.append(attendee) flag = 0 else: - if attendee.value.split(':')[1] == email_address: + if attendee.value.split(':')[1] in email_address: ans.vevent.attendee_list.append(attendee) flag = 0 if flag: @@ -212,14 +212,16 @@ if __name__=="__main__": to = organizer(ans) message = EmailMessage() - message['From'] = email_address + message['From'] = email_address[0] message['To'] = to message['Subject'] = subject - mailtext = "'%s has %s'" % (email_address, accept_decline.lower()) + mailtext = "'%s has %s'" % (email_address[0], accept_decline.lower()) message.add_alternative(mailtext, subtype='plain') message.add_alternative(ans.serialize(), subtype='calendar', params={ 'method': 'REPLY' }) + if accept_decline == "Accepted" or accept_decline == "Tentative": + os.system("khal import --batch %s" % (args[0],)) execute(sendmail() + ['--', to], message.as_bytes()) diff --git a/play-minecraft b/play-minecraft new file mode 100755 index 0000000..de3c434 --- /dev/null +++ b/play-minecraft @@ -0,0 +1,6 @@ +#!/bin/sh + +pkill -f launcher +xinput set-prop 11 290 0 +minecraft-launcher +xinput set-prop 11 290 1 diff --git a/view_attachment b/view_attachment new file mode 100755 index 0000000..6c26df8 --- /dev/null +++ b/view_attachment @@ -0,0 +1,129 @@ +#!/bin/bash +# +# Author: Eric Gebhart +# Email: e.a.gebhart@gmail.com +# +# Purpose: To be called by mutt as indicated by .mailcap to handle mail attachments. +# +# Function: Copy the given file to a temporary directory so mutt +# Won't delete it before it is read by the application. +# +# Along the way, discern the file type or use the type +# That is given. +# +# Finally use 'open' or 'open -a' if the third argument is +# given. +# +# +# Arguments: +# +# $1 is the file +# $2 is the type - for those times when file magic isn't enough. +# I frequently get html mail that has no extension +# and file can't figure out what it is. +# +# Set to '-' if you don't want the type to be discerned. +# Many applications can sniff out the type on their own. +# And they do a better job of it too. +# +# Open Office and MS Office for example. +# +# $3 is open with. as in open -a 'open with this .app' foo.xls +# +# Examples: These are typical .mailcap entries which use this program. +# +# Image/JPEG; /Users/vdanen/.mutt/view_attachment %s +# Image/PNG; /Users/vdanen/.mutt/view_attachment %s +# Image/GIF; /Users/vdanen/.mutt/view_attachment %s +# +# Application/PDF; /Users/vdanen/.mutt/view_attachment %s +# +# #This HTML example passes the type because file doesn't always work and +# #there aren't always extensions. +# +# text/html; /Users/vdanen/.mutt/view_attachment %s html +# +# # If your Start OpenOffice.org.app is spelled with a space like this one, <-- +# # then you'll need to precede the space with a \ . I found that too painful +# # and renamed it with an _. +# +# Application/vnd.ms-excel; /Users/vdanen/.mutt/view_attachment %s "-" '/Applications/OpenOffice.org1.1.2/Start_OpenOffice.org.app' +# Application/msword; /Users/vdanen/.mutt/view_attachment %s "-" '/Applications/OpenOffice.org1.1.2/Start_OpenOffice.org.app' +# +# +# Debugging: If you have problems set debug to 'yes'. That will cause a debug file +# be written to /tmp/mutt_attach/debug so you can see what is going on. +# +# See Also: The man pages for open, file, basename +# + +# the tmp directory to use. +tmpdir="$HOME/.mutt/tmp/mutt_attach" + +# the name of the debug file if debugging is turned on. +debug_file=$tmpdir/debug + +# debug. yes or no. +#debug="no" +debug="yes" + +type=$2 +open_with=$3 + +# make sure the tmpdir exists. +mkdir -p $tmpdir + +# clean it out. Remove this if you want the directory +# to accumulate attachment files. +rm -rf $tmpdir/* + +# Mutt puts everything in /tmp by default. +# This gets the basic filename from the full pathname. +filename=`basename $1` + +# get rid of the extenson and save the name for later. +#file=`echo $filename | cut -d"." -f1` +file=`echo $filename | sed 's/\.[^.]*$//'` + +if [ $debug = "yes" ]; then + echo "1:" $1 " 2:" $2 " 3:" $3 > $debug_file + echo "Filename:"$filename >> $debug_file + echo "File:"$file >> $debug_file + echo "===========================" >> $debug_file +fi + +# if the type is empty then try to figure it out. +if [ -z $type ]; then + #type=`file -bi $1 | cut -d"/" -f2` + type=`file -bi $1 | sed -e 's/^[^\/]*\///' -e 's/;.*$//'` +fi + +# if the type is '-' then we don't want to mess with type. +# Otherwise we are rebuilding the name. Either from the +# type that was passed in or from the type we discerned. +if [ $type = "-" ]; then + newfile=$filename +else + newfile=$file.$type +fi + +newfile=$tmpdir/$newfile + +# Copy the file to our new spot so mutt can't delete it +# before the app has a chance to view it. +cp $1 $newfile + +if [ $debug = "yes" ]; then + echo "File:" $file "TYPE:" $type >> $debug_file + echo "Newfile:" $newfile >> $debug_file + echo "Open With:" $open_with >> $debug_file +fi + +# If there's no 'open with' then we can let preview do it's thing. +# Otherwise we've been told what to use. So do an open -a. + +if [ -z $open_with ]; then + open $newfile +else + open -a "$open_with" $newfile +fi |
