8000 recite english words · codepongo/utocode@57cd57c · GitHub
[go: up one dir, main page]

Skip to content

Commit 57cd57c

Browse files
committed
recite english words
1 parent 725a45d commit 57cd57c

13 files changed

+529
-0
lines changed

recite/getch.py

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
class _Getch:
2+
"""Gets a single character from standard input. Does not echo to the
3+
screen."""
4+
def __init__(self):
5+
try:
6+
self.impl = _GetchWindows()
7+
except ImportError:
8+
self.impl = _GetchUnix()
9+
10+
def __call__(self): return self.impl()
11+
12+
13+
class _GetchUnix:
14+
def __init__(self):
15+
import tty, sys
16+
17+
def __call__(self):
18+
import sys, tty, termios
19+
fd = sys.stdin.fileno()
20+
old_settings = termios.tcgetattr(fd)
21+
try:
22+
tty.setraw(sys.stdin.fileno())
23+
ch = sys.stdin.read(1)
24+
finally:
25+
termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)
26+
return ch
27+
28+
29+
class _GetchWindows:
30+
def __init__(self):
31+
import msvcrt
32+
33+
def __call__(self):
34+
import msvcrt
35+
return msvcrt.getch()
36+
37+
38+
getch = _Getch()

recite/install.py

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import sys
2+
import os
3+
import shutil
4+
def copytree_f(s, d):
5+
if os.path.isdir(d):
6+
shutil.rmtree(d)
7+
shutil.copytree(s, d)
8+
if __name__ == '__main__':
9+
folders = ['review',
10+
'sound',
11+
'vocabulary',
12+
]
13+
out = sys.argv[1]
14+
for f in folders:
15+
d = os.path.join(out, f)
16+
if not os.path.exists(d):
17+
os.mkdir(d)
18+
libs = [
19+
'mp3play',
20+
]
21+
for l in libs:
22+
copytree_f(l, os.path.join(out, l))
23+
excutes = [
24+
'getch.py',
25+
'p.py',
26+
'phonetic_with_bing.py',
27+
'recite.py',
28+
'sound.py',
29+
'review.py',
30+
'p.bat',
31+
'r.bat',
32+
'review.bat',
33+
's.bat',
34+
]
35+
for e in excutes:
36+
shutil.copy(e, out)
37+
38+
if os.path.isfile('install.py'):
39+
with open('install.py', 'rb') as f:
40+
with open(os.path.join(out, 'backup.py'), 'wb') as o:
41+
o.write(f.read().replace('out = sys.argv[1]', 'out = "%s"' % (os.path.abspath('.').replace('\\', '\\\\'))))
42+

recite/mp3play/__init__.py

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
import os
2+
3+
if os.name == 'nt':
4+
from .windows import AudioClip as _PlatformSpecificAudioClip
5+
else:
6+
raise Exception("mp3play can't run on your operating system.")
7+
8+
def load(filename):
9+
"""Return an AudioClip for the given filename."""
10+
return AudioClip(filename)
11+
12+
class AudioClip(object):
13+
__slots__ = ['_clip']
14+
15+
def __init__(self, filename):
16+
"""Create an AudioClip for the given filename."""
17+
self._clip = _PlatformSpecificAudioClip(filename)
18+
19+
def play(self, start_ms=None, end_ms=None):
20+
"""
21+
Start playing the audio clip, and return immediately. Play from
22+
start_ms to end_ms if either is specified; defaults to beginning
23+
and end of the clip. Returns immediately. If end_ms is specified
24+
as smaller than start_ms, nothing happens.
25+
"""
26+
if end_ms != None and end_ms < start_ms:
27+
return
28+
else:
29+
return self._clip.play(start_ms, end_ms)
30+
31+
def volume(self, level):
32+
"""Sets the volume between 0 and 100."""
33+
assert level >=0 and level <= 100
34+
return self._clip.volume(level)
35+
36+
def isplaying(self):
37+
"""Returns True if the clip is currently playing. Note that if a
38+
clip is paused, or if you called play() on a clip and playing has
39+
completed, this returns False."""
40+
return self._clip.isplaying()
41+
42+
def pause(self):
43+
"""Pause the clip if it is currently playing."""
44+
return self._clip.pause()
45+
46+
def unpause(self):
47+
"""Unpause the clip if it is currently paused."""
48+
return self._clip.unpause()
49+
50+
def ispaused(self):
51+
"""Returns True if the clip is currently paused."""
52+
return self._clip.ispaused()
53+
54+
def stop(self):
55+
"""Stop the audio clip if it is playing."""
56+
return self._clip.stop()
57+
58+
def seconds(self):
59+
"""
60+
Returns the length in seconds of the audio clip, rounded to the
61+
nearest second.
62+
"""
63+
return int(round(float(self.milliseconds()) / 1000))
64+
65+
def milliseconds(self):
66+
"""Returns the length in milliseconds of the audio clip."""
67+
return self._clip.milliseconds()

recite/mp3play/windows.py

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
import random
2+
3+
from ctypes import windll, c_buffer
4+
5+
class _mci:
6+
def __init__(self):
7+
self.w32mci = windll.winmm.mciSendStringA
8+
self.w32mcierror = windll.winmm.mciGetErrorStringA
9+
10+
def send(self, command):
11+
buffer = c_buffer(255)
12+
errorcode = self.w32mci(str(command), buffer, 254, 0)
13+
if errorcode:
14+
return errorcode, self.get_error(errorcode)
15+
else:
16+
return errorcode, buffer.value
17+
18+
def get_error(self, error):
19+
error = int(error)
20+
buffer = c_buffer(255)
21+
self.w32mcierror(error, buffer, 254)
22+
return buffer.value
23+
24+
def directsend(self, txt):
25+
(err, buf) = self.send(txt)
26+
if err != 0:
27+
print 'Error %s for "%s": %s' % (str(err), txt, buf)
28+
return (err, buf)
29+
30+
# TODO: detect errors in all mci calls
31+
class AudioClip(object):
32+
def __init__(self, filename):
33+
filename = filename.replace('/', '\\')
34+
self.filename = filename
35+
self._alias = 'mp3_%s' % str(random.random())
36+
37+
self._mci = _mci()
38+
39+
self._mci.directsend(r'open "%s" alias %s' % (filename, self._alias ))
40+
self._mci.directsend('set %s time format milliseconds' % self._alias)
41+
42+
err, buf=self._mci.directsend('status %s length' % self._alias)
43+
self._length_ms = int(buf)
44+
45+
def volume(self, level):
46+
"""Sets the volume between 0 and 100."""
47+
self._mci.directsend('setaudio %s volume to %d' %
48+
(self._alias, level * 10) )
49+
50+
def play(self, start_ms=None, end_ms=None):
51+
start_ms = 0 if not start_ms else start_ms
52+
end_ms = self.milliseconds() if not end_ms else end_ms
53+
err,buf=self._mci.directsend('play %s from %d to %d'
54+
% (self._alias, start_ms, end_ms) )
55+
56+
def isplaying(self):
57+
return self._mode() == 'playing'
58+
59+
def _mode(self):
60+
err, buf = self._mci.directsend('status %s mode' % self._alias)
61+
return buf
62+
63+
def pause(self):
64+
self._mci.directsend('pause %s' % self._alias)
65+
66+
def unpause(self):
67+
self._mci.directsend('resume %s' % self._alias)
68+
69+
def ispaused(self):
70+
return self._mode() == 'paused'
71+
72+
def stop(self):
73+
self._mci.directsend('stop %s' % self._alias)
74+
self._mci.directsend('seek %s to start' % self._alias)
75+
76+
def milliseconds(self):
77+
return self._length_ms
78+
79+
# TODO: this closes the file even if we're still playing.
80+
# no good. detect isplaying(), and don't die till then!
81+
def __del__(self):
82+
self._mci.directsend('close %s' % self._alias)

recite/p.bat

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
@echo off
2+
python p.py %1

recite/p.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
import sound
2+
import sys
3+
w = sys.argv[1].decode(sys.stdin.encoding).encode('gbk')
4+
sound.sound(w)

recite/phonetic_with_bing.py

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
import urllib
2+
import HTMLParser
3+
us_tbl = {
4+
'\xca\x8a':'U',
5+
'\xc9\xaa':'I',
6+
'\xc3\xa6':'Q',
7+
'\xc9\x91':'A',
8+
'\xc9\x9c':'E',
9+
'\xc9\x94':'C',
10+
'\xca\x8c':'V',
11+
'\xc9\x99':'E',
12+
'\xce\xb8':'T',
13+
'\xc5\x8b':'N',
14+
'\xc3\xb0':'D',
15+
'\xca\x83':'S',
16+
'\xca\x92':'Z',
17+
'\xc9\xa1':'g',
18+
'\xcb\x88':"`",
19+
'\xcb\x8c':',',
20+
'\xc9\x9b':'e',
21+
'\xc9\x92':'o',
22+
'\xcb\x90':'',
23+
24+
}
25+
def phonetic_readability(s, tbl):
26+
for k, v in tbl.items():
27+
s = s.replace(k, v)
28+
return s
29+
30+
def get_from_bing(w):
31+
url = 'http://cn.bing.com/dict/?q=%s' % w
32+
class Parser(HTMLParser.HTMLParser):
33+
def __init__(self):
34+
HTMLParser.HTMLParser.__init__(self)
35+
self.content = ''
36+
37+
def handle_starttag(self, tag, attrs):
38+
if tag == 'meta':
39+
for key, value in attrs:
40+
if key == 'name' and value == 'description':
41+
for k, v in attrs:
42+
if k == 'content':
43+
self.content = v
44+
return
45+
rep = urllib.urlopen(url)
46+
html = rep.read()
47+
p = Parser()
48+
try:
49+
p.feed(html)
50+
except:
51+
pass
52+
content = p.content
53+
phonetic = {'en':'', 'us':'', 'us_unicode':''}
54+
start = content.find('[')
55+
end = content.find(']')
56+
if start == -1 or end == -1:
57+
return phonetic
58+
phonetic['us'] = phonetic_readability(content[start+1:end], us_tbl)
59+
start = content[end+1:].find('[')
60+
end = content[end+1:].find('[')
61+
phonetic['en'] = content[start+1:end]
62+
phonetic['us_unicode'] = repr(content[start+1:end])
63+
return phonetic
64+
65+
66+
if __name__ == '__main__':
67+
import sys
68+
p = get_from_bing(sys.argv[1])
69+
print p
70+
71+
72+
73+
74+

recite/r.bat

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
@echo off
2+
call python recite.py

0 commit comments

Comments
 (0)
0