[nvda-addons] Re: commit/tip_of_the_day: derekriemer: basic command line program to make adding tips more sane. Uses my easy ui framework.

  • From: driemer.riemer@xxxxxxxxx
  • To: nvda-addons@xxxxxxxxxxxxx
  • Date: Fri, 1 Apr 2016 12:08:50 -0600

Note that I think I accidentally pushed the file I didn't intend here and I 
will remove it later. This shouldn't be a huge deal as it was just an error 
trace log. This program is definitely not very robust at this point it is just 
designed to make adding tips for the tip of the day out on a tiny bit easier 
for me so I don't have to type out Json manually.

Sent from my heavily encrypted iPhone.
Please disregard errors as this is a smaller device.

On Apr 1, 2016, at 11:47, commits-noreply@xxxxxxxxxxxxx wrote:

1 new commit in tip_of_the_day:

https://bitbucket.org/nvdaaddonteam/tip_of_the_day/commits/5e62732fb648/ ;
Changeset: 5e62732fb648 Branch: master User: derekriemer Date: 2016-04-01 
17:47:29+00:00 Summary: basic command line program to make adding tips more 
sane. Uses my easy ui framework.

Affected #: 5 files

diff --git a/a.txt b/a.txt deleted file mode 100644 index f971240..0000000 
--- a/a.txt +++ /dev/null @@ -1,113 +0,0 @@ -EEEEEE 
-====================================================================== 
-ERROR: test_app_exists (test_TipsReader.TipsTester) 
----------------------------------------------------------------------- 
-Traceback (most recent call last):

File “C:\Users\derek_2\Google Drive\tip_of_the_day\tests\test_TipsReader.py”, 
line 11, in setUp

self.t1 = Tips(os.path.join(os.path.dirname(__file__), “assetts”, "t1.json"))

File “globalPlugins\tipsReader.py”, line 13, in _init_

self.tipsDict = j = json.load(tipsFile)

File “C:\Python27\lib\json\__init__.py”, line 290, in load

**kw)

File “C:\Python27\lib\json\__init__.py”, line 338, in loads

return _default_decoder.decode(s)

File “C:\Python27\lib\json\decoder.py”, line 366, in decode

obj, end = self.raw_decode(s, idx=_w(s, 0).end())

File “C:\Python27\lib\json\decoder.py”, line 382, in raw_decode

obj, end = self.scan_once(s, idx)

-ValueError: Expecting property name: line 14 column 13 (char 341) – 
-====================================================================== 
-ERROR: test_app_is_correct (test_TipsReader.TipsTester) 
----------------------------------------------------------------------- 
-Traceback (most recent call last):

File “C:\Users\derek_2\Google Drive\tip_of_the_day\tests\test_TipsReader.py”, 
line 11, in setUp

self.t1 = Tips(os.path.join(os.path.dirname(__file__), “assetts”, "t1.json"))

File “globalPlugins\tipsReader.py”, line 13, in _init_

self.tipsDict = j = json.load(tipsFile)

File “C:\Python27\lib\json\__init__.py”, line 290, in load

**kw)

File “C:\Python27\lib\json\__init__.py”, line 338, in loads

return _default_decoder.decode(s)

File “C:\Python27\lib\json\decoder.py”, line 366, in decode

obj, end = self.raw_decode(s, idx=_w(s, 0).end())

File “C:\Python27\lib\json\decoder.py”, line 382, in raw_decode

obj, end = self.scan_once(s, idx)

-ValueError: Expecting property name: line 14 column 13 (char 341) – 
-====================================================================== 
-ERROR: test_get_invalid_tip_name_is_None (test_TipsReader.TipsTester) 
----------------------------------------------------------------------- 
-Traceback (most recent call last):

File “C:\Users\derek_2\Google Drive\tip_of_the_day\tests\test_TipsReader.py”, 
line 11, in setUp

self.t1 = Tips(os.path.join(os.path.dirname(__file__), “assetts”, "t1.json"))

File “globalPlugins\tipsReader.py”, line 13, in _init_

self.tipsDict = j = json.load(tipsFile)

File “C:\Python27\lib\json\__init__.py”, line 290, in load

**kw)

File “C:\Python27\lib\json\__init__.py”, line 338, in loads

return _default_decoder.decode(s)

File “C:\Python27\lib\json\decoder.py”, line 366, in decode

obj, end = self.raw_decode(s, idx=_w(s, 0).end())

File “C:\Python27\lib\json\decoder.py”, line 382, in raw_decode

obj, end = self.scan_once(s, idx)

-ValueError: Expecting property name: line 14 column 13 (char 341) – 
-====================================================================== 
-ERROR: test_iterateTips (test_TipsReader.TipsTester) 
----------------------------------------------------------------------- 
-Traceback (most recent call last):

File “C:\Users\derek_2\Google Drive\tip_of_the_day\tests\test_TipsReader.py”, 
line 11, in setUp

self.t1 = Tips(os.path.join(os.path.dirname(__file__), “assetts”, "t1.json"))

File “globalPlugins\tipsReader.py”, line 13, in _init_

self.tipsDict = j = json.load(tipsFile)

File “C:\Python27\lib\json\__init__.py”, line 290, in load

**kw)

File “C:\Python27\lib\json\__init__.py”, line 338, in loads

return _default_decoder.decode(s)

File “C:\Python27\lib\json\decoder.py”, line 366, in decode

obj, end = self.raw_decode(s, idx=_w(s, 0).end())

File “C:\Python27\lib\json\decoder.py”, line 382, in raw_decode

obj, end = self.scan_once(s, idx)

-ValueError: Expecting property name: line 14 column 13 (char 341) – 
-====================================================================== 
-ERROR: test_malformedJson (test_TipsReader.TipsTester) 
----------------------------------------------------------------------- 
-Traceback (most recent call last):

File “C:\Users\derek_2\Google Drive\tip_of_the_day\tests\test_TipsReader.py”, 
line 11, in setUp

self.t1 = Tips(os.path.join(os.path.dirname(__file__), “assetts”, "t1.json"))

File “globalPlugins\tipsReader.py”, line 13, in _init_

self.tipsDict = j = json.load(tipsFile)

File “C:\Python27\lib\json\__init__.py”, line 290, in load

**kw)

File “C:\Python27\lib\json\__init__.py”, line 338, in loads

return _default_decoder.decode(s)

File “C:\Python27\lib\json\decoder.py”, line 366, in decode

obj, end = self.raw_decode(s, idx=_w(s, 0).end())

File “C:\Python27\lib\json\decoder.py”, line 382, in raw_decode

obj, end = self.scan_once(s, idx)

-ValueError: Expecting property name: line 14 column 13 (char 341) – 
-====================================================================== 
-ERROR: test_non_existant_file (test_TipsReader.TipsTester) 
----------------------------------------------------------------------- 
-Traceback (most recent call last):

File “C:\Users\derek_2\Google Drive\tip_of_the_day\tests\test_TipsReader.py”, 
line 11, in setUp

self.t1 = Tips(os.path.join(os.path.dirname(__file__), “assetts”, "t1.json"))

File “globalPlugins\tipsReader.py”, line 13, in _init_

self.tipsDict = j = json.load(tipsFile)

File “C:\Python27\lib\json\__init__.py”, line 290, in load

**kw)

File “C:\Python27\lib\json\__init__.py”, line 338, in loads

return _default_decoder.decode(s)

File “C:\Python27\lib\json\decoder.py”, line 366, in decode

obj, end = self.raw_decode(s, idx=_w(s, 0).end())

File “C:\Python27\lib\json\decoder.py”, line 382, in raw_decode

obj, end = self.scan_once(s, idx)

-ValueError: Expecting property name: line 14 column 13 (char 341) – 
----------------------------------------------------------------------- -Ran 
6 tests in 0.015s – -FAILED (errors=6)

diff --git a/easy_ui/__init__.py b/easy_ui/__init__.py new file mode 100644 
index 0000000..6424e6d --- /dev/null +++ b/easy_ui/__init__.py @@ -0,0 +1,90 
@@ +from _future_ import print_function +from genericValidators import * 
+from sys import version + +#monkeypatch python 2's stupid builtin input 
function to replace it with something safe. +if version[0] == “2”: +       
input = raw_input + + + +class Ui: +    def initialize_menu(self): +    
print("{options:^40}\n\n".format(options="options:")) + 
print("{index:<10}{item:>10}".format(item="exit", index=0)) + + for index, 
item in enumerate(self.funcDict.keys()): + 
print("{index:<10}{item:>10}".format(item=item, index=index+1)) + 
self.max=len(list(self.funcDict.keys())) + +    def getraw_input(self): +     
  while True: +   try: + self.choice=int(input("enter your choice")) +    if 
self.choice>self.max or self.choice < 0: +   raise ValueError(&q uot;Value 
too large") +                             break + except KeyboardInterrupt as 
e: +        exit() +        except ValueError as e: +                         
      if str(e)=="Value too large": + print("item not in the menu.") +        
else: + print("That was a bad option you gave me.\nEnter one of the numbers 
above.") +  self.initialize_menu() + continue +     if 0 == self.choice: + 
print("Good Bye, Exiting program.") +    exit() + + +    def callIt(self): + 
option=list(self.funcDict.values())[self.choice-1] # get the 3-toople. + #an 
option is a toople of the function, and then a toople of 2-tooples with items 
in the form of (type, prompt) +  args=[] +       for theType, toPrint in 
option[1:]: +   while True: +   print("{:^20}".format(toPrint)) +       
#types provided by the class to make life easier. +     #This is a map of 
genaric types, or miscellaneous types, and their respective built-in helper. 
If the python type is the same as the builtin type to map on then just put 
the s ame thing on both sides of the mapping. +       #To get at the actual 
type that we should have, a self.validated variable should be provided with 
what we want to actually give the function. See the YesNo typeclass for an 
example. + inMap = False # if it is in the map we set this to True. + 
self.validators.update({ +   bool : YesNo, + TrueBool : TrueBool +   } ) + if 
theType in self.validators: +  inMap = True +  theOldType = theType + theType 
= self.validators[theOldType] +  try: + that = theType(str(input())) +   if 
inMap: +     args.append(that.validated) +   else: + args.append(that) +     
break + except ValueError: +    print("{:^20}".format("bad option? Try 
entering that again.")) +        option[0](*args) #call it with our just 
built list of arguements. + + + def __init__(self, funcDict, validators = {}, 
once = True): + self.funcDict=funcDict + self.validators = validators + 
loop=True +       while loop: + self.initializ e_menu() + loop=once + 
self.getraw_input() +       self.callIt() #choice is passed in on self.choice 
so we don't need to send it in here. + + + + + + + + + +

diff --git a/easy_ui/genericValidators.py b/easy_ui/genericValidators.py new 
file mode 100644 index 0000000..1ffe48b --- /dev/null +++ 
b/easy_ui/genericValidators.py @@ -0,0 +1,40 @@ +class 
GenericValueMap(object): +      """A generic user input validator. To 
implement your own custom behavior for validating user input before functions 
get called, you should subclass this as it handles some things with the ui 
manager. """ +   def __init__(self, n): +        """ The user need not worry 
about the details of the constructor. If you wish to write your own 
constructor, the burden of correctly interfacing with the ui manager is up to 
you. """ +        if self._validate(n): + return +        else: #Erronious 
input. +       raise ValueError("Bad option") + +      def _validate(self, 
n): +       """ This function receives an input n (of type str) which is 
unsanitized and unvalidated. The job of the validator is to set 
self.validated to n' whe re n' is the value (in python) that should be passed 
to the callable by the ui manager. + @n: String of raw user input. + 
@returns: True/false. True on success of setting self.validated, and False on 
failure. Note that False represents user error. + """ +   raise 
NotImplementedError + + +class YesNo(GenericValueMap): +  def _validate(self, 
n): +       n=n.lower() +   if n=="y" or n=="yes": +        self.validated = 
True + elif n=="n" or n=="no": + self.validated = False +      else: + return 
False #Error on the users part. + return True #success. + +class 
TrueBool(GenericValueMap): #A boolean like on a test. + def _validate(self, 
n): +       n = n.lower() + if n == “true”: +       self.validated = True +   
              return True +   elif n == “false”: + self.validated = False +   
return True +           else: + return False +

diff --git a/tip_creator.py b/tip_creator.py new file mode 100644 index 
0000000..cc94c75 --- /dev/null +++ b/tip_creator.py @@ -0,0 +1,51 @@ +import 
collections +import json +import easy_ui + +def save(): +        with 
open("tips.json", “w”) as f: +     json.dump(tips, f, separators = (",", " : 
“), indent=4) + +def list(): +        for i in tips["tips"].keys(): + print i 
+ + +def add(title, level, description): +      if title in tips["tips"]: +   
  print “you already added this tip.” +   return +        tip = {} +      if 
level not in xrange(1,7): + print “bad level.” +     return +        
tip["level”] = [ +      ["beginner"], + ["intermediate"], +     ["advanced"], 
+ ["beginner", “intermediate"], + ["intermediate”, “advanced"], + 
["beginner”, “intermediate”, “advanced”] +      ][level-1] +    
tip["description"] = descripti on +     tips["tips"][title] = tip + +ui = { + 
  “List Tips” : ( +       list, + ), +    “Add a Tip” : ( +       add, +  
(str, “Type your Title",), +            (int, “1 for beginner, 2 for 
intermediate, 3 for advanced, 4 for beginner and intermediate, 5 for 
intermediate and advanced, or 6 for all three.",), +  (str, "the tip, \n 
makes a new line.",), +      ), +    "Save” : ( +    save, + ) +} + +with 
open("tips.json”) as tipsFile: +   tips = json.load(tipsFile, 
object_pairs_hook=collections.OrderedDict) +easy_ui.Ui(ui) #runs the ui 
asking the user what they want. +

diff --git a/tips.json b/tips.json index 54929ed..888f81b 100644 --- 
a/tips.json +++ b/tips.json @@ -1,14 +1,38 @@

{
    "type" : "app",
“appname” : “winword”,

+ “appname” : “None”,

"tips" : {
“using word”: {

“level” : ["beginner"],

“description”: “fish”

+ “The NVDA Key” : { + “description” : “The NVDA key is either the insert, 
extended insert, or caps lock key.\nTo use the NVDA key, you should configure 
NVDA to use a key. By default, the NVDA key is set to the two insert keys. 
The key that is long and skinny on the number pad is the insert key. Also, 
the extended insert key is probably towards the top row of keys. To set your 
NVDA keys, open the keyboard settings dialog with the NVDA key and the letter 
n, and then find keyboard settings in the general settings menu.” + “level” : 
[ + “beginner”, + “intermediate”, + “advanced” + ],

},
“words famous gripe” : {

“level” : ["beginner"],

“description” : “bad”

+ “Accessing the NVDA Menu.” : { + “level” : [ + “beginner”, + 
“intermediate”, + “advanced” + ], + “description” : “To access the NVDA menu, 
you should be able to press the NVDA key, and the letter N at the same time.” 
+ }, + “Getting help” : { + “description” : “To find help, use the NVDA key 
and N (open the NVDA menu), then go to help. There is a users guide and quick 
key reference sheet.”, + “level” : [ + “beginner”, + “intermediate”, + 
“advanced” + ] + }, + “Preferences” : { + “description” : “To customize NVDA, 
use the NVDA key and N to open the NVDA menu, and then open the preferenc es 
sub-menu. Then press enter on the preferences you want to change and make the 
changes.”, + “level” : [ + “beginner”, + “intermediate”, + “advanced” + ]

        }
    }
}
\ No newline at end of file

Repository URL: https://bitbucket.org/nvdaaddonteam/tip_of_the_day/



This is a commit notification from bitbucket.org. You are receiving this 
because you have the service enabled, addressing the recipient of this email.

Other related posts:

  • » [nvda-addons] Re: commit/tip_of_the_day: derekriemer: basic command line program to make adding tips more sane. Uses my easy ui framework. - driemer . riemer