February 24, 2009, 10:39 am
I’m pleased to report that Tubecaster 2.0.1 for Windows is now available for download. Click here to go to the downloads page on the Tubecaster homepage.
Highlights of this release:
- Supported media formats:
- MP3
- FLAC
- WAV
- Ogg Vorbis
- AVI
- MPG
- MP4
- 3GP
- Additional language support: Afrikaans
- Automatically downloads HD version of the chosen video if available
- Proxy server support
- Login support – for downloading videos marked as private or age restricted
I’m keen to get feedback on what people would like to see in the next release. You can report bugs or request new features here. On that same site you can also vote for features that have already been requested. The more votes a feature gets the more likely and quickly it is to be implemented.
-Wayne
February 22, 2009, 11:45 pm
In the latest version of Tubecaster I’ve come to the point of needing to give users the option of storing passwords on disk. Needless to say the very thought sent shivers down my spine. I was stressing over the problem of how to store passwords for automatic retrieval and use by the software, but at the same time making them secure enough that they can’t easily be retrieved by nasty people. This led me to make this post on Stack Overflow.
Basically the given solution I thought best (at least for Windows platforms at this stage) is to use Windows’ built-in Data Protection API. This led to a follow-up question on Stack Overflow where the user “dF” pointed me to an example which uses Python’s ctypes library. This works really well and I’ve tidied up the example and added a couple of functions to make it more user friendly and play nicely as a library. You can view and download it below. Thanks again to “dF” and “Crusher Joe”.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
| # DPAPI access library
# This file uses code originally created by Crusher Joe:
# http://article.gmane.org/gmane.comp.python.ctypes/420
#
from ctypes import *
from ctypes.wintypes import DWORD
LocalFree = windll.kernel32.LocalFree
memcpy = cdll.msvcrt.memcpy
CryptProtectData = windll.crypt32.CryptProtectData
CryptUnprotectData = windll.crypt32.CryptUnprotectData
CRYPTPROTECT_UI_FORBIDDEN = 0x01
extraEntropy = "cl;ad13 \0al;323kjd #(adl;k$#ajsd"
class DATA_BLOB(Structure):
_fields_ = [("cbData", DWORD), ("pbData", POINTER(c_char))]
def getData(blobOut):
cbData = int(blobOut.cbData)
pbData = blobOut.pbData
buffer = c_buffer(cbData)
memcpy(buffer, pbData, cbData)
LocalFree(pbData);
return buffer.raw
def Win32CryptProtectData(plainText, entropy):
bufferIn = c_buffer(plainText, len(plainText))
blobIn = DATA_BLOB(len(plainText), bufferIn)
bufferEntropy = c_buffer(entropy, len(entropy))
blobEntropy = DATA_BLOB(len(entropy), bufferEntropy)
blobOut = DATA_BLOB()
if CryptProtectData(byref(blobIn), u"python_data", byref(blobEntropy),
None, None, CRYPTPROTECT_UI_FORBIDDEN, byref(blobOut)):
return getData(blobOut)
else:
return ""
def Win32CryptUnprotectData(cipherText, entropy):
bufferIn = c_buffer(cipherText, len(cipherText))
blobIn = DATA_BLOB(len(cipherText), bufferIn)
bufferEntropy = c_buffer(entropy, len(entropy))
blobEntropy = DATA_BLOB(len(entropy), bufferEntropy)
blobOut = DATA_BLOB()
if CryptUnprotectData(byref(blobIn), None, byref(blobEntropy), None, None,
CRYPTPROTECT_UI_FORBIDDEN, byref(blobOut)):
return getData(blobOut)
else:
return ""
def cryptData(text):
return Win32CryptProtectData(text, extraEntropy)
def decryptData(cipher_text):
return Win32CryptUnprotectData(cipher_text, extraEntropy) |