[mail] Include all mail configs in dotfiles
This commit is contained in:
parent
3e756eed3c
commit
89ff511993
9 changed files with 614 additions and 1 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -1,6 +1,6 @@
|
|||
*.swp
|
||||
.DS_Store
|
||||
f/
|
||||
bin/mail-sync.sh
|
||||
**/newsboat/.newsboat/cache.db*
|
||||
**/newsboat/.newsboat/history.cmdline
|
||||
**/newsboat/.newsboat/ttrss-pw.txt
|
||||
|
|
16
mail/aerc/accounts.conf
Normal file
16
mail/aerc/accounts.conf
Normal file
|
@ -0,0 +1,16 @@
|
|||
[migadu]
|
||||
#
|
||||
# Switching back to notmuch (from maildir experiment)
|
||||
#
|
||||
source = notmuch:///home/adam/Maildir
|
||||
maildir-store = /home/adam/Maildir
|
||||
outgoing = /home/adam/.local/bin/aerc-notmuch-send migadu
|
||||
default = INBOX
|
||||
from = Adam Cooper <adam@theadamcooper.com>
|
||||
|
||||
# notmuch does not support the copy-to directive
|
||||
# copy-to = Sent
|
||||
check-mail = 4m
|
||||
check-mail-cmd = /home/adam/.local/bin/mail-sync.sh
|
||||
check-mail-timeout = 20s
|
||||
|
191
mail/aerc/aerc.conf
Normal file
191
mail/aerc/aerc.conf
Normal file
|
@ -0,0 +1,191 @@
|
|||
#
|
||||
# aerc main configuration
|
||||
|
||||
[ui]
|
||||
#
|
||||
# Describes the format for each row in a mailbox view. This field is compatible
|
||||
# with mutt's printf-like syntax.
|
||||
#
|
||||
# Default: %D %-17.17n %Z %s
|
||||
index-format=%D %-17.17n %Z %s
|
||||
|
||||
#
|
||||
# See time.Time#Format at https://godoc.org/time#Time.Format
|
||||
#
|
||||
# Default: 2006-01-02 03:04 PM (ISO 8601 + 12 hour time)
|
||||
timestamp-format=2006-01-02 15:04
|
||||
|
||||
#
|
||||
# Width of the sidebar, including the border.
|
||||
#
|
||||
# Default: 20
|
||||
sidebar-width=20
|
||||
|
||||
#
|
||||
# Message to display when viewing an empty folder.
|
||||
#
|
||||
# Default: (no messages)
|
||||
empty-message=(no messages)
|
||||
|
||||
# Message to display when no folders exists or are all filtered
|
||||
#
|
||||
# Default: (no folders)
|
||||
empty-dirlist=(no folders)
|
||||
|
||||
# Enable mouse events in the ui, e.g. clicking and scrolling with the mousewheel
|
||||
#
|
||||
# Default: false
|
||||
mouse-enabled=false
|
||||
|
||||
#
|
||||
# Ring the bell when new messages are received
|
||||
#
|
||||
# Default: true
|
||||
new-message-bell=true
|
||||
|
||||
# Marker to show before a pinned tab's name.
|
||||
#
|
||||
# Default: `
|
||||
pinned-tab-marker='`'
|
||||
|
||||
# Describes the format string to use for the directory list
|
||||
#
|
||||
# Default: %n %>r
|
||||
dirlist-format=%n %>r
|
||||
|
||||
# List of space-separated criteria to sort the messages by, see *sort*
|
||||
# command in *aerc*(1) for reference. Prefixing a criterion with "-r "
|
||||
# reverses that criterion.
|
||||
#
|
||||
# Example: "from -r date"
|
||||
#
|
||||
# Default: ""
|
||||
sort=-r date
|
||||
|
||||
# Moves to next message when the current message is deleted
|
||||
#
|
||||
# Default: true
|
||||
next-message-on-delete=true
|
||||
|
||||
fuzzy-complete=true
|
||||
|
||||
[viewer]
|
||||
#
|
||||
# Specifies the pager to use when displaying emails. Note that some filters
|
||||
# may add ANSI codes to add color to rendered emails, so you may want to use a
|
||||
# pager which supports ANSI codes.
|
||||
#
|
||||
# Default: less -R
|
||||
pager=less -R
|
||||
|
||||
#
|
||||
# If an email offers several versions (multipart), you can configure which
|
||||
# mimetype to prefer. For example, this can be used to prefer plaintext over
|
||||
# html emails.
|
||||
#
|
||||
# Default: text/plain,text/html
|
||||
alternatives=text/html,text/plain
|
||||
|
||||
#
|
||||
# Default setting to determine whether to show full headers or only parsed
|
||||
# ones in message viewer.
|
||||
#
|
||||
# Default: false
|
||||
show-headers=false
|
||||
|
||||
#
|
||||
# Layout of headers when viewing a message. To display multiple headers in the
|
||||
# same row, separate them with a pipe, e.g. "From|To". Rows will be hidden if
|
||||
# none of their specified headers are present in the message.
|
||||
#
|
||||
# Default: From|To,Cc|Bcc,Date,Subject
|
||||
header-layout=From|To,Cc|Bcc,Date,Subject|Labels
|
||||
|
||||
# Whether to always show the mimetype of an email, even when it is just a single part
|
||||
#
|
||||
# Default: false
|
||||
always-show-mime=false
|
||||
|
||||
# How long to wait after the last input before auto-completion is triggered.
|
||||
#
|
||||
# Default: 250ms
|
||||
completion-delay=250ms
|
||||
|
||||
#
|
||||
# Global switch for completion popovers
|
||||
#
|
||||
# Default: true
|
||||
completion-popovers=true
|
||||
|
||||
[compose]
|
||||
#
|
||||
# Specifies the command to run the editor with. It will be shown in an embedded
|
||||
# terminal, though it may also launch a graphical window if the environment
|
||||
# supports it. Defaults to $EDITOR, or vi.
|
||||
editor=
|
||||
|
||||
#
|
||||
# Default header fields to display when composing a message. To display
|
||||
# multiple headers in the same row, separate them with a pipe, e.g. "To|From".
|
||||
#
|
||||
# Default: To|From,Subject
|
||||
header-layout=To|From,Subject
|
||||
|
||||
#
|
||||
# Specifies the command to be used to tab-complete email addresses. Any
|
||||
# occurrence of "%s" in the address-book-cmd will be replaced with what the
|
||||
# user has typed so far.
|
||||
#
|
||||
# The command must output the completions to standard output, one completion
|
||||
# per line. Each line must be tab-delimited, with an email address occurring as
|
||||
# the first field. Only the email address field is required. The second field,
|
||||
# if present, will be treated as the contact name. Additional fields are
|
||||
# ignored.
|
||||
address-book-cmd=khard email --parsable --remove-first-line %s
|
||||
|
||||
[filters]
|
||||
#
|
||||
# Filters allow you to pipe an email body through a shell command to render
|
||||
# certain emails differently, e.g. highlighting them with ANSI escape codes.
|
||||
#
|
||||
# The first filter which matches the email's mimetype will be used, so order
|
||||
# them from most to least specific.
|
||||
#
|
||||
# You can also match on non-mimetypes, by prefixing with the header to match
|
||||
# against (non-case-sensitive) and a comma, e.g. subject,text will match a
|
||||
# subject which contains "text". Use header,~regex to match against a regex.
|
||||
subject,~^\[PATCH=awk -f /usr/local/share/aerc/filters/hldiff
|
||||
text/html=/usr/local/share/aerc/filters/html
|
||||
text/*=awk -f /usr/local/share/aerc/filters/plaintext
|
||||
image/*=catimg -w $(tput cols) -
|
||||
|
||||
[triggers]
|
||||
#
|
||||
# Triggers specify commands to execute when certain events occur.
|
||||
#
|
||||
# Example:
|
||||
# new-email=exec notify-send "New email from %n" "%s"
|
||||
|
||||
#
|
||||
# Executed when a new email arrives in the selected folder
|
||||
new-email=exec notify-send "New email from %n" "%s"
|
||||
|
||||
[templates]
|
||||
# Templates are used to populate email bodies automatically.
|
||||
#
|
||||
|
||||
# The directories where the templates are stored. It takes a colon-separated
|
||||
# list of directories.
|
||||
#
|
||||
# default: /usr/local/share/aerc/templates/
|
||||
template-dirs=/usr/local/share/aerc/templates/
|
||||
|
||||
# The template to be used for quoted replies.
|
||||
#
|
||||
# default: quoted_reply
|
||||
quoted-reply=quoted_reply
|
||||
|
||||
# The template to be used for forward as body.
|
||||
#
|
||||
# default: forward_as_body
|
||||
forwards=forward_as_body
|
106
mail/aerc/binds.conf
Normal file
106
mail/aerc/binds.conf
Normal file
|
@ -0,0 +1,106 @@
|
|||
# Binds are of the form <key sequence> = <command to run>
|
||||
# To use '=' in a key sequence, substitute it with "Eq": "<Ctrl+Eq>"
|
||||
# If you wish to bind #, you can wrap the key sequence in quotes: "#" = quit
|
||||
<C-p> = :prev-tab<Enter>
|
||||
<C-n> = :next-tab<Enter>
|
||||
<C-t> = :term<Enter>
|
||||
|
||||
[messages]
|
||||
q = :quit<Enter>
|
||||
|
||||
j = :next<Enter>
|
||||
<Down> = :next<Enter>
|
||||
<C-d> = :next 50%<Enter>
|
||||
<C-f> = :next 100%<Enter>
|
||||
<PgDn> = :next -s 100%<Enter>
|
||||
|
||||
k = :prev<Enter>
|
||||
<Up> = :prev<Enter>
|
||||
<C-u> = :prev 50%<Enter>
|
||||
<C-b> = :prev 100%<Enter>
|
||||
<PgUp> = :prev -s 100%<Enter>
|
||||
g = :select 0<Enter>
|
||||
G = :select -1<Enter>
|
||||
|
||||
J = :next-folder<Enter>
|
||||
K = :prev-folder<Enter>
|
||||
|
||||
v = :mark -t<Enter>
|
||||
V = :mark -v<Enter>
|
||||
|
||||
<Enter> = :view<Enter>
|
||||
# Replace deletion key bindings to move items to the trash
|
||||
# d = :prompt 'Really delete this message?' 'delete-message'<Enter>
|
||||
# D = :delete<Enter>
|
||||
d = :mv Trash<Enter>
|
||||
D = :mv Trash<Enter>
|
||||
A = :archive flat<Enter>
|
||||
|
||||
C = :compose<Enter>
|
||||
|
||||
rr = :reply -a<Enter>
|
||||
rq = :reply -aq<Enter>
|
||||
Rr = :reply<Enter>
|
||||
Rq = :reply -q<Enter>
|
||||
|
||||
c = :cf<space>
|
||||
$ = :term<space>
|
||||
! = :term<space>
|
||||
| = :pipe<space>
|
||||
|
||||
/ = :search<space>
|
||||
\ = :filter<space>
|
||||
n = :next-result<Enter>
|
||||
N = :prev-result<Enter>
|
||||
|
||||
[view]
|
||||
q = :close<Enter>
|
||||
| = :pipe<space>
|
||||
D = :delete<Enter>
|
||||
S = :save<space>
|
||||
A = :archive flat<Enter>
|
||||
|
||||
f = :forward<Enter>
|
||||
rr = :reply -a<Enter>
|
||||
rq = :reply -aq<Enter>
|
||||
Rr = :reply<Enter>
|
||||
Rq = :reply -q<Enter>
|
||||
|
||||
H = :toggle-headers<Enter>
|
||||
<C-k> = :prev-part<Enter>
|
||||
<C-j> = :next-part<Enter>
|
||||
J = :next<Enter>
|
||||
K = :prev<Enter>
|
||||
|
||||
[compose]
|
||||
# Keybindings used when the embedded terminal is not selected in the compose
|
||||
# view
|
||||
$ex = <C-x>
|
||||
<C-k> = :prev-field<Enter>
|
||||
<C-j> = :next-field<Enter>
|
||||
<tab> = :next-field<Enter>
|
||||
|
||||
[compose::editor]
|
||||
# Keybindings used when the embedded terminal is selected in the compose view
|
||||
$noinherit = true
|
||||
$ex = <C-x>
|
||||
<C-k> = :prev-field<Enter>
|
||||
<C-j> = :next-field<Enter>
|
||||
<C-p> = :prev-tab<Enter>
|
||||
<C-n> = :next-tab<Enter>
|
||||
|
||||
[compose::review]
|
||||
# Keybindings used when reviewing a message to be sent
|
||||
y = :send<Enter>
|
||||
n = :abort<Enter>
|
||||
p = :postpone<Enter>
|
||||
q = :abort<Enter>
|
||||
e = :edit<Enter>
|
||||
a = :attach<space>
|
||||
|
||||
[terminal]
|
||||
$noinherit = true
|
||||
$ex = <C-x>
|
||||
|
||||
<C-p> = :prev-tab<Enter>
|
||||
<C-n> = :next-tab<Enter>
|
37
mail/aerc/mail-sync.sh.example
Executable file
37
mail/aerc/mail-sync.sh.example
Executable file
|
@ -0,0 +1,37 @@
|
|||
#!/bin/sh
|
||||
|
||||
OFFLINEIMAP=$(pgrep offlineimap)
|
||||
NOTMUCH=$(pgrep notmuch)
|
||||
|
||||
if [ -n "$OFFLINEIMAP" ] || [ -n "$NOTMUCH" ]; then
|
||||
echo "Already running one instance of offlineimap or notmuch. Exiting..."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo "Deleting messages tagged as *deleted*"
|
||||
notmuch search --format=text0 --output=files tag:deleted | xargs -0 --no-run-if-empty rm -v
|
||||
|
||||
offlineimap -o
|
||||
notmuch new
|
||||
|
||||
# retag all "new" messages "inbox" and "unread"
|
||||
notmuch tag +inbox +unread -new -- tag:new
|
||||
|
||||
# mailing lists
|
||||
notmuch tag +mailinglist -- to:xmonad@haskell.org
|
||||
notmuch tag +mailinglist -- to:guile-user@gnu.org
|
||||
notmuch tag +mailinglist -- to:zsh-users@zsh.org
|
||||
notmuch tag +mailinglist -- to:qutebrowser@lists.qutebrowser.org
|
||||
notmuch tag +mailinglist -- to:~rjarry/aerc-discuss@lists.sr.ht
|
||||
|
||||
# TODO: Confirm that we need to do this
|
||||
# move tagged items across folders and retag
|
||||
notmuch search --output=files tag:trash and not folder:Trash | xargs mv -t /home/adam/Maildir/Trash/cur/
|
||||
notmuch tag +trash -inbox -sent -archive -junk -drafts -- folder:Trash and not tag:trash
|
||||
|
||||
# move unimportant institutional messages to the trash after a couple of days
|
||||
notmuch tag +trash -inbox -- date:..2d and tag:mailinglist
|
||||
notmuch tag +trash -inbox -- date:..2d and from:@facebookmail.com
|
||||
notmuch tag +trash -inbox -- date:..2d and from:noreply@twitch.tv
|
||||
notmuch tag +trash -inbox -- date:..2d and from:messages-noreply@linkedin.com
|
||||
|
87
mail/notmuch/.notmuch-config
Normal file
87
mail/notmuch/.notmuch-config
Normal file
|
@ -0,0 +1,87 @@
|
|||
# .notmuch-config - Configuration file for the notmuch mail system
|
||||
#
|
||||
# For more information about notmuch, see https://notmuchmail.org
|
||||
|
||||
# Database configuration
|
||||
#
|
||||
# The only value supported here is 'path' which should be the top-level
|
||||
# directory where your mail currently exists and to where mail will be
|
||||
# delivered in the future. Files should be individual email messages.
|
||||
# Notmuch will store its database within a sub-directory of the path
|
||||
# configured here named ".notmuch".
|
||||
#
|
||||
[database]
|
||||
path=/home/adam/Maildir
|
||||
|
||||
# User configuration
|
||||
#
|
||||
# Here is where you can let notmuch know how you would like to be
|
||||
# addressed. Valid settings are
|
||||
#
|
||||
# name Your full name.
|
||||
# primary_email Your primary email address.
|
||||
# other_email A list (separated by ';') of other email addresses
|
||||
# at which you receive email.
|
||||
#
|
||||
# Notmuch will use the various email addresses configured here when
|
||||
# formatting replies. It will avoid including your own addresses in the
|
||||
# recipient list of replies, and will set the From address based on the
|
||||
# address to which the original email was addressed.
|
||||
#
|
||||
[user]
|
||||
name=Adam Cooper
|
||||
primary_email=adam@theadamcooper.com
|
||||
|
||||
# Configuration for "notmuch new"
|
||||
#
|
||||
# The following options are supported here:
|
||||
#
|
||||
# tags A list (separated by ';') of the tags that will be
|
||||
# added to all messages incorporated by "notmuch new".
|
||||
#
|
||||
# ignore A list (separated by ';') of file and directory names
|
||||
# that will not be searched for messages by "notmuch new".
|
||||
#
|
||||
# NOTE: *Every* file/directory that goes by one of those
|
||||
# names will be ignored, independent of its depth/location
|
||||
# in the mail store.
|
||||
#
|
||||
[new]
|
||||
|
||||
# Search configuration
|
||||
#
|
||||
# The following option is supported here:
|
||||
#
|
||||
# exclude_tags
|
||||
# A ;-separated list of tags that will be excluded from
|
||||
# search results by default. Using an excluded tag in a
|
||||
# query will override that exclusion.
|
||||
#
|
||||
[search]
|
||||
|
||||
# Maildir compatibility configuration
|
||||
#
|
||||
# The following option is supported here:
|
||||
#
|
||||
# synchronize_flags Valid values are true and false.
|
||||
#
|
||||
# If true, then the following maildir flags (in message filenames)
|
||||
# will be synchronized with the corresponding notmuch tags:
|
||||
#
|
||||
# Flag Tag
|
||||
# ---- -------
|
||||
# D draft
|
||||
# F flagged
|
||||
# P passed
|
||||
# R replied
|
||||
# S unread (added when 'S' flag is not present)
|
||||
#
|
||||
# The "notmuch new" command will notice flag changes in filenames
|
||||
# and update tags, while the "notmuch tag" and "notmuch restore"
|
||||
# commands will notice tag changes and update flags in filenames
|
||||
#
|
||||
[maildir]
|
||||
synchronize_flags=true
|
||||
|
||||
[index]
|
||||
header.Context-Transfer-Encoding=Context-Transfer-Encoding
|
25
mail/offlineimap/config
Normal file
25
mail/offlineimap/config
Normal file
|
@ -0,0 +1,25 @@
|
|||
[general]
|
||||
accounts = main
|
||||
pythonfile = /home/adam/.config/offlineimap/offlineimap.py
|
||||
maxsyncaccounts = 1
|
||||
|
||||
[Account main]
|
||||
localrepository = main-local
|
||||
remoterepository = main-remote
|
||||
# autorefresh = 0.5
|
||||
# quick = 10
|
||||
|
||||
[Repository main-local]
|
||||
type = Maildir
|
||||
localfolders = ~/Maildir
|
||||
|
||||
[Repository main-remote]
|
||||
type = IMAP
|
||||
remotehost = imap.migadu.com
|
||||
remoteuser = adam@theadamcooper.com
|
||||
remotepasseval = get_pw_from_attrs("service", "migadu")
|
||||
starttls = yes
|
||||
ssl = yes
|
||||
sslcacertfile = /etc/ssl/certs/ca-certificates.crt
|
||||
# keepalive = 60
|
||||
# holdconnectionopen = yes
|
151
mail/offlineimap/offlineimap.py
Normal file
151
mail/offlineimap/offlineimap.py
Normal file
|
@ -0,0 +1,151 @@
|
|||
'''
|
||||
offlineimap.py
|
||||
This provides a handful of functions for retrieving secrets from GNOME Keyring
|
||||
using the libsecret API. See the documentation for each function
|
||||
'''
|
||||
|
||||
from gi import require_version
|
||||
require_version('Secret', '1')
|
||||
from gi.repository import Secret
|
||||
|
||||
def get_pw_from_desc(pw_desc) :
|
||||
'''
|
||||
This function returns the password for an item in the default keyring
|
||||
which contains the description provided.
|
||||
Use this function if you created a password using the dialogue in Seahorse
|
||||
'''
|
||||
# Get service
|
||||
service = Secret.Service.get_sync(Secret.ServiceFlags.LOAD_COLLECTIONS)
|
||||
|
||||
# Get default keyring
|
||||
keyring = Secret.Collection.for_alias_sync(service, "default", \
|
||||
Secret.CollectionFlags.NONE, None)
|
||||
|
||||
# Get keyring items
|
||||
items = keyring.get_items()
|
||||
|
||||
# Load secrets
|
||||
Secret.Item.load_secrets_sync(items)
|
||||
|
||||
# Loop through items, find the matching one and return its password
|
||||
password = None
|
||||
for item in items :
|
||||
if item.get_label() == pw_desc :
|
||||
password = item.get_secret().get_text()
|
||||
break
|
||||
|
||||
# Close connection
|
||||
service.disconnect()
|
||||
|
||||
return password
|
||||
|
||||
def get_pw_from_attrs(*attr_val_pairs) :
|
||||
'''
|
||||
This function returns the password for an item in the default keyring
|
||||
which contains all of the attribute value pairs provided as arguments.
|
||||
Use this function if you created a password using the secret-tool command
|
||||
or another such program that interfaces with libsecret
|
||||
'''
|
||||
# Check the list of attr-val pairs is present and contains an even number
|
||||
# of elements
|
||||
if attr_val_pairs == () :
|
||||
raise TypeError("get_pw_from_attrs() at least 1 attribute-value pair " \
|
||||
"must be supplied")
|
||||
if len(attr_val_pairs) % 2 != 0 :
|
||||
raise TypeError("get_pw_from_attrs() incomplete attribute-value " \
|
||||
"pair was supplied")
|
||||
|
||||
# Get service
|
||||
service = Secret.Service.get_sync(Secret.ServiceFlags.LOAD_COLLECTIONS)
|
||||
|
||||
# Get default keyring
|
||||
keyring = Secret.Collection.for_alias_sync(service, "default", \
|
||||
Secret.CollectionFlags.NONE, None)
|
||||
|
||||
# Get keyring items
|
||||
items = keyring.get_items()
|
||||
|
||||
# Load secrets
|
||||
Secret.Item.load_secrets_sync(items)
|
||||
|
||||
# Loop through items, find the one which contains all supplied attr_val
|
||||
# pairs and return its password
|
||||
password = None
|
||||
for item in items :
|
||||
attrs = item.get_attributes()
|
||||
match = True
|
||||
for x in range(0, len(attr_val_pairs), 2) :
|
||||
key = attr_val_pairs[x]
|
||||
value = attr_val_pairs[x + 1]
|
||||
try :
|
||||
if attrs[key] != value :
|
||||
match = False
|
||||
break
|
||||
except KeyError :
|
||||
match = False
|
||||
break
|
||||
if match :
|
||||
password = item.get_secret().get_text()
|
||||
break
|
||||
|
||||
# Close connection
|
||||
service.disconnect()
|
||||
|
||||
return password
|
||||
|
||||
def get_val_from_attrs(attr, *attr_val_pairs) :
|
||||
'''
|
||||
This function returns the value for a given attribute. The first item
|
||||
found that contains that attribute will be the one that is used. To ensure
|
||||
that the correct item is chosen, any number of attribute-value pairs can
|
||||
be optionally supplied as arguments and only the item which contains all
|
||||
of those attr-val pairs (along with the main attr) will be used.
|
||||
Use this function if you created a password using the secret-tool command
|
||||
or another such program that interfaces with libsecret
|
||||
'''
|
||||
# Check the list of attr-val pairs contains an even number of elements
|
||||
# if it exists
|
||||
if attr_val_pairs != () :
|
||||
if len(attr_val_pairs) % 2 != 0 :
|
||||
raise TypeError("get_val_from_attrs() incomplete attribute-value " \
|
||||
"pair was supplied")
|
||||
|
||||
# Get service
|
||||
service = Secret.Service.get_sync(Secret.ServiceFlags.LOAD_COLLECTIONS)
|
||||
|
||||
# Get default keyring
|
||||
keyring = Secret.Collection.for_alias_sync(service, "default", \
|
||||
Secret.CollectionFlags.NONE, None)
|
||||
|
||||
# Get keyring items
|
||||
items = keyring.get_items()
|
||||
|
||||
# Loop through items, find the one which contains the supplied attribute
|
||||
# (plus any attr_val pairs if specified) and return that attribute's
|
||||
# value
|
||||
attr_value = None
|
||||
for item in items :
|
||||
attrs = item.get_attributes()
|
||||
try :
|
||||
attrs[attr]
|
||||
except KeyError :
|
||||
continue
|
||||
match = True
|
||||
for x in range(0, len(attr_val_pairs), 2) :
|
||||
key = attr_val_pairs[x]
|
||||
value = attr_val_pairs[x + 1]
|
||||
try :
|
||||
if attrs[key] != value :
|
||||
match = False
|
||||
break
|
||||
except KeyError :
|
||||
match = False
|
||||
break
|
||||
if match :
|
||||
attr_value = attrs[attr]
|
||||
break
|
||||
|
||||
# Close connection
|
||||
service.disconnect()
|
||||
|
||||
return attr_value
|
Loading…
Reference in a new issue