Commit 344295d4 authored by putro's avatar putro

first commit

parents
#!/usr/bin/env python
import os
import sys
from utils import download
import subprocess
class MixError(Exception):
pass
def process_args():
""" Process command line arguments """
from optparse import OptionParser
use = "nymhelper.py [options] \nexcept for -C, all other options are ju" \
"st used to send a message from command line\nfor normal use do " \
"not use any options"
parser = OptionParser(usage=use)
parser.add_option("-C", "--config", action="store", dest="config",
default="config.ini",
help="config file to use nym to send the message from.")
parser.add_option("-n", "--nym", action="store", dest="nym", type="int",
help="nym to send the message from.")
parser.add_option("-s", "--subject", action="store", dest="subject",
help="subject for the message to be sent.")
parser.add_option("-r", "--recipient", action="store", dest="recipient",
help="recipient of the message to be sent.")
parser.add_option("-t", "--text", action="store", dest="text",
help="text of the message to be sent.")
parser.add_option("-c", "--chain", action="store", dest="chain",
help="remailer chain to send the message through \
(example: -c \"remailer1,remailer2\").")
return parser.parse_args()
def checkAscii(file):
""" Check if the a file is pure ascii """
import codecs
bad = 0
f = codecs.open(file, encoding='ascii')
lines = open(file).readlines()
for i in range(0, len(lines)):
try:
l = f.readline()
except:
num = i + 1
print "config file problem (%s): line %d contains non-ascii " \
"character, fix it" % (file, num)
bad = 1
break
f.close()
return bad
def InitialCheck():
global configfile
global opts, args
(opts, args) = process_args()
if opts.config:
configfile = os.path.dirname(sys.argv[0]) + "/" + opts.config
else:
configfile = os.path.dirname(sys.argv[0]) + "/config.ini"
def OptionsCheck(config):
""" performs some checks """
try:
f = open(os.path.dirname(sys.argv[0]) + "/check", "w")
except:
print "Error: you cannot write %s, fix permission or launch this script from another directory" % options['path'] + "/" + options['stats-file']
sys.exit()
else:
f.close()
os.remove(os.path.dirname(sys.argv[0]) + "/check")
# try:
# f = open(os.path.dirname(sys.argv[0]) + "/" + config['stats']['stats_mlist'], "r")
# except:
# download(config['stats']['stats_mlist'], config)
# else:
# f.close()
try:
download(config['stats']['stats_mlist'], config)
except:
print "Error: cannot download fresh remailer stats"
try:
mix = subprocess.Popen(config['options']['mixmaster'], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
except OSError: # usally means that mixmaster could not be executed
raise MixError('Could not find mixmaster binary.')
#import gpgfuncts
#gpgfuncts.selectSecKey(options.nym_email)
return True
import os
import sys
import checks
from configobj import ConfigObj, ConfigObjError
class ConfigError(Exception):
pass
configfile = os.path.dirname(sys.argv[0]) + "/config.ini"
try:
config = ConfigObj(configfile, file_error=True)
except (ConfigObjError, IOError), e:
print 'Could not read "%s": %s' % (configfile, e)
sys.exit(-1)
nyms = config['nym']
def writeConfig():
config.write()
def checkSection(section, config=config):
if section in listSection(config):
return True
def listSection(config):
return config.keys()
def configSection(nym, subject, subj_type, passphrase=""):
config['nym'][nym] = {}
config['nym'][nym]['subject'] = subject
config['nym'][nym]['subj_type'] = subj_type
config['nym'][nym]['passphrase'] = passphrase
def checkNymConfig(nym):
return nyms.has_key(nym)
def nymList(nyms):
nymlist = []
for n in nyms.keys():
nymlist.append(n)
return nymlist
def printNymList():
nymlist = nymList()
counter = 0
for n in nymlist:
print counter, "-", n
counter += 1
return counter
"""
@version: 0.96(2010-08-29)
@note:
ABOUT EASYGUI
EasyGui provides an easy-to-use interface for simple GUI interaction
with a user. It does not require the programmer to know anything about
tkinter, frames, widgets, callbacks or lambda. All GUI interactions are
invoked by simple function calls that return results.
@note:
WARNING about using EasyGui with IDLE
You may encounter problems using IDLE to run programs that use EasyGui. Try it
and find out. EasyGui is a collection of Tkinter routines that run their own
event loops. IDLE is also a Tkinter application, with its own event loop. The
two may conflict, with unpredictable results. If you find that you have
problems, try running your EasyGui program outside of IDLE.
Note that EasyGui requires Tk release 8.0 or greater.
@note:
LICENSE INFORMATION
EasyGui version 0.96
Copyright (c) 2010, Stephen Raymond Ferg
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
3. The name of the author may not be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@note:
ABOUT THE EASYGUI LICENSE
This license is what is generally known as the "modified BSD license",
aka "revised BSD", "new BSD", "3-clause BSD".
See http://www.opensource.org/licenses/bsd-license.php
This license is GPL-compatible.
See http://en.wikipedia.org/wiki/License_compatibility
See http://www.gnu.org/licenses/license-list.html#GPLCompatibleLicenses
The BSD License is less restrictive than GPL.
It allows software released under the license to be incorporated into proprietary products.
Works based on the software may be released under a proprietary license or as closed source software.
http://en.wikipedia.org/wiki/BSD_licenses#3-clause_license_.28.22New_BSD_License.22.29
"""
egversion = __doc__.split()[1]
__all__ = ['ynbox'
, 'ccbox'
, 'boolbox'
, 'indexbox'
, 'msgbox'
, 'buttonbox'
, 'integerbox'
, 'multenterbox'
, 'enterbox'
, 'exceptionbox'
, 'choicebox'
, 'codebox'
, 'textbox'
, 'diropenbox'
, 'fileopenbox'
, 'filesavebox'
, 'passwordbox'
, 'multpasswordbox'
, 'multchoicebox'
, 'abouteasygui'
, 'egversion'
, 'egdemo'
, 'EgStore'
]
import sys, os
import string
import pickle
import traceback
#--------------------------------------------------
# check python version and take appropriate action
#--------------------------------------------------
"""
From the python documentation:
sys.hexversion contains the version number encoded as a single integer. This is
guaranteed to increase with each version, including proper support for non-
production releases. For example, to test that the Python interpreter is at
least version 1.5.2, use:
if sys.hexversion >= 0x010502F0:
# use some advanced feature
...
else:
# use an alternative implementation or warn the user
...
"""
if sys.hexversion >= 0x020600F0:
runningPython26 = True
else:
runningPython26 = False
if sys.hexversion >= 0x030000F0:
runningPython3 = True
else:
runningPython3 = False
try:
from PIL import Image as PILImage
from PIL import ImageTk as PILImageTk
PILisLoaded = True
except:
PILisLoaded = False
if runningPython3:
from tkinter import *
import tkinter.filedialog as tk_FileDialog
from io import StringIO
else:
from Tkinter import *
import tkFileDialog as tk_FileDialog
from StringIO import StringIO
def write(*args):
args = [str(arg) for arg in args]
args = " ".join(args)
sys.stdout.write(args)
def writeln(*args):
write(*args)
sys.stdout.write("\n")
say = writeln
if TkVersion < 8.0 :
stars = "*"*75
writeln("""\n\n\n""" + stars + """
You are running Tk version: """ + str(TkVersion) + """
You must be using Tk version 8.0 or greater to use EasyGui.
Terminating.
""" + stars + """\n\n\n""")
sys.exit(0)
def dq(s):
return '"%s"' % s
rootWindowPosition = "+300+200"
PROPORTIONAL_FONT_FAMILY = ("MS", "Sans", "Serif")
MONOSPACE_FONT_FAMILY = ("Courier")
PROPORTIONAL_FONT_SIZE = 10
MONOSPACE_FONT_SIZE = 9 #a little smaller, because it it more legible at a smaller size
TEXT_ENTRY_FONT_SIZE = 12 # a little larger makes it easier to see
#STANDARD_SELECTION_EVENTS = ["Return", "Button-1"]
STANDARD_SELECTION_EVENTS = ["Return", "Button-1", "space"]
# Initialize some global variables that will be reset later
__choiceboxMultipleSelect = None
__widgetTexts = None
__replyButtonText = None
__choiceboxResults = None
__firstWidget = None
__enterboxText = None
__enterboxDefaultText=""
__multenterboxText = ""
choiceboxChoices = None
choiceboxWidget = None
entryWidget = None
boxRoot = None
ImageErrorMsg = (
"\n\n---------------------------------------------\n"
"Error: %s\n%s")
#-------------------------------------------------------------------
# various boxes built on top of the basic buttonbox
#-----------------------------------------------------------------------
#-----------------------------------------------------------------------
# ynbox
#-----------------------------------------------------------------------
def ynbox(msg="Shall I continue?"
, title=" "
, choices=("Yes", "No")
, image=None
):
"""
Display a msgbox with choices of Yes and No.
The default is "Yes".
The returned value is calculated this way::
if the first choice ("Yes") is chosen, or if the dialog is cancelled:
return 1
else:
return 0
If invoked without a msg argument, displays a generic request for a confirmation
that the user wishes to continue. So it can be used this way::
if ynbox(): pass # continue
else: sys.exit(0) # exit the program
@arg msg: the msg to be displayed.
@arg title: the window title
@arg choices: a list or tuple of the choices to be displayed
"""
return boolbox(msg, title, choices, image=image)
#-----------------------------------------------------------------------
# ccbox
#-----------------------------------------------------------------------
def ccbox(msg="Shall I continue?"
, title=" "
, choices=("Continue", "Cancel")
, image=None
):
"""
Display a msgbox with choices of Continue and Cancel.
The default is "Continue".
The returned value is calculated this way::
if the first choice ("Continue") is chosen, or if the dialog is cancelled:
return 1
else:
return 0
If invoked without a msg argument, displays a generic request for a confirmation
that the user wishes to continue. So it can be used this way::
if ccbox():
pass # continue
else:
sys.exit(0) # exit the program
@arg msg: the msg to be displayed.
@arg title: the window title
@arg choices: a list or tuple of the choices to be displayed
"""
return boolbox(msg, title, choices, image=image)
#-----------------------------------------------------------------------
# boolbox
#-----------------------------------------------------------------------
def boolbox(msg="Shall I continue?"
, title=" "
, choices=("Yes","No")
, image=None
):
"""
Display a boolean msgbox.
The default is the first choice.
The returned value is calculated this way::
if the first choice is chosen, or if the dialog is cancelled:
returns 1
else:
returns 0
"""
reply = buttonbox(msg=msg, choices=choices, title=title, image=image)
if reply == choices[0]: return 1
else: return 0
#-----------------------------------------------------------------------
# indexbox
#-----------------------------------------------------------------------
def indexbox(msg="Shall I continue?"
, title=" "
, choices=("Yes","No")
, image=None
):
"""
Display a buttonbox with the specified choices.
Return the index of the choice selected.
"""
reply = buttonbox(msg=msg, choices=choices, title=title, image=image)
index = -1
for choice in choices:
index = index + 1
if reply == choice: return index
raise AssertionError(
"There is a program logic error in the EasyGui code for indexbox.")
#-----------------------------------------------------------------------
# msgbox
#-----------------------------------------------------------------------
def msgbox(msg="(Your message goes here)", title=" ", ok_button="OK",image=None,root=None):
"""
Display a messagebox
"""
if type(ok_button) != type("OK"):
raise AssertionError("The 'ok_button' argument to msgbox must be a string.")
return buttonbox(msg=msg, title=title, choices=[ok_button], image=image,root=root)
#-------------------------------------------------------------------
# buttonbox
#-------------------------------------------------------------------
def buttonbox(msg="",title=" "
,choices=("Button1", "Button2", "Button3")
, image=None
, root=None
):
"""
Display a msg, a title, and a set of buttons.
The buttons are defined by the members of the choices list.
Return the text of the button that the user selected.
@arg msg: the msg to be displayed.
@arg title: the window title
@arg choices: a list or tuple of the choices to be displayed
"""
global boxRoot, __replyButtonText, __widgetTexts, buttonsFrame
# Initialize __replyButtonText to the first choice.
# This is what will be used if the window is closed by the close button.
__replyButtonText = choices[0]
if root:
root.withdraw()
boxRoot = Toplevel(master=root)
boxRoot.withdraw()
else:
boxRoot = Tk()
boxRoot.withdraw()
boxRoot.protocol('WM_DELETE_WINDOW', denyWindowManagerClose )
boxRoot.title(title)
boxRoot.iconname('Dialog')
boxRoot.geometry(rootWindowPosition)
boxRoot.minsize(400, 100)
# ------------- define the messageFrame ---------------------------------
messageFrame = Frame(master=boxRoot)
messageFrame.pack(side=TOP, fill=BOTH)
# ------------- define the imageFrame ---------------------------------
tk_Image = None
if image:
imageFilename = os.path.normpath(image)
junk,ext = os.path.splitext(imageFilename)
if os.path.exists(imageFilename):
if ext.lower() in [".gif", ".pgm", ".ppm"]:
tk_Image = PhotoImage(master=boxRoot, file=imageFilename)
else:
if PILisLoaded:
try:
pil_Image = PILImage.open(imageFilename)
tk_Image = PILImageTk.PhotoImage(pil_Image, master=boxRoot)
except:
msg += ImageErrorMsg % (imageFilename,
"\nThe Python Imaging Library (PIL) could not convert this file to a displayable image."
"\n\nPIL reports:\n" + exception_format())
else: # PIL is not loaded
msg += ImageErrorMsg % (imageFilename,
"\nI could not import the Python Imaging Library (PIL) to display the image.\n\n"
"You may need to install PIL\n"
"(http://www.pythonware.com/products/pil/)\n"
"to display " + ext + " image files.")
else:
msg += ImageErrorMsg % (imageFilename, "\nImage file not found.")
if tk_Image:
imageFrame = Frame(master=boxRoot)
imageFrame.pack(side=TOP, fill=BOTH)
label = Label(imageFrame,image=tk_Image)
label.image = tk_Image # keep a reference!
label.pack(side=TOP, expand=YES, fill=X, padx='1m', pady='1m')
# ------------- define the buttonsFrame ---------------------------------
buttonsFrame = Frame(master=boxRoot)
buttonsFrame.pack(side=TOP, fill=BOTH)
# -------------------- place the widgets in the frames -----------------------
messageWidget = Message(messageFrame, text=msg, width=400)
messageWidget.configure(font=(PROPORTIONAL_FONT_FAMILY,PROPORTIONAL_FONT_SIZE))
messageWidget.pack(side=TOP, expand=YES, fill=X, padx='3m', pady='3m')
__put_buttons_in_buttonframe(choices)
# -------------- the action begins -----------
# put the focus on the first button
__firstWidget.focus_force()
boxRoot.deiconify()
boxRoot.mainloop()
boxRoot.destroy()
if root: root.deiconify()
return __replyButtonText
#-------------------------------------------------------------------
# integerbox
#-------------------------------------------------------------------
def integerbox(msg=""
, title=" "
, default=""
, lowerbound=0
, upperbound=99
, image = None
, root = None
, **invalidKeywordArguments
):
"""
Show a box in which a user can enter an integer.
In addition to arguments for msg and title, this function accepts
integer arguments for "default", "lowerbound", and "upperbound".
The default argument may be None.
When the user enters some text, the text is checked to verify that it
can be converted to an integer between the lowerbound and upperbound.
If it can be, the integer (not the text) is returned.
If it cannot, then an error msg is displayed, and the integerbox is
redisplayed.
If the user cancels the operation, None is returned.
NOTE that the "argLowerBound" and "argUpperBound" arguments are no longer
supported. They have been replaced by "upperbound" and "lowerbound".
"""
if "argLowerBound" in invalidKeywordArguments:
raise AssertionError(
"\nintegerbox no longer supports the 'argLowerBound' argument.\n"
+ "Use 'lowerbound' instead.\n\n")
if "argUpperBound" in invalidKeywordArguments:
raise AssertionError(
"\nintegerbox no longer supports the 'argUpperBound' argument.\n"
+ "Use 'upperbound' instead.\n\n")
if default != "":
if type(default) != type(1):
raise AssertionError(
"integerbox received a non-integer value for "
+ "default of " + dq(str(default)) , "Error")
if type(lowerbound) != type(1):
raise AssertionError(
"integerbox received a non-integer value for "
+ "lowerbound of " + dq(str(lowerbound)) , "Error")
if type(upperbound) != type(1):
raise AssertionError(
"integerbox received a non-integer value for "
+ "upperbound of " + dq(str(upperbound)) , "Error")
if msg == "":
msg = ("Enter an integer between " + str(lowerbound)
+ " and "
+ str(upperbound)
)
while 1:
reply = enterbox(msg, title, str(default), image=image, root=root)
if reply == None: return None
try:
reply = int(reply)
except: