[Pymoul-svn] SF.net SVN: pymoul: [111] pymoul/trunk
Status: Alpha
Brought to you by:
tiran
|
From: <ti...@us...> - 2007-02-01 00:05:40
|
Revision: 111
http://pymoul.svn.sourceforge.net/pymoul/?rev=111&view=rev
Author: tiran
Date: 2007-01-31 16:05:40 -0800 (Wed, 31 Jan 2007)
Log Message:
-----------
Added some informations and donate link to README.txt
Modified Paths:
--------------
pymoul/trunk/README.txt
pymoul/trunk/src/moul/file/tests/test_wdysini.py
pymoul/trunk/src/moul/file/wdysini.py
pymoul/trunk/src/moul/qt/mainwindow.py
Added Paths:
-----------
pymoul/trunk/src/moul/file/directories.py
Modified: pymoul/trunk/README.txt
===================================================================
--- pymoul/trunk/README.txt 2007-01-31 15:40:51 UTC (rev 110)
+++ pymoul/trunk/README.txt 2007-02-01 00:05:40 UTC (rev 111)
@@ -0,0 +1,19 @@
+=========================================
+Python library for Myst Online : Uru Live
+=========================================
+
+About
+=====
+
+pyMoul is a set of Python libraries around MOUL (Myst Online : Uru Live). At
+the moment the main focus is on the Qt4 based graphical tool.
+
+Donate
+======
+
+If you like the tool and find it usful please donate some money. You can
+use the link below to send me money over PayPal. You don't need a PayPal
+account. A credit card or bank account is sufficient.
+
+https://www.paypal.com/cgi-bin/webscr?cmd=_xclick&business=christian%40cheimes%2ede&item_name=Donate%20for%20Tiran%27s%20open%20source%20activities&page_style=PayPal&no_shipping=2&cn=Your%20note%20for%20me&tax=0¤cy_code=EUR&lc=DE&bn=PP%2dDonationsBF&charset=UTF%2d8
+
Added: pymoul/trunk/src/moul/file/directories.py
===================================================================
--- pymoul/trunk/src/moul/file/directories.py (rev 0)
+++ pymoul/trunk/src/moul/file/directories.py 2007-02-01 00:05:40 UTC (rev 111)
@@ -0,0 +1,78 @@
+# pyMoul - Python interface to Myst Online URU Live
+# Copyright (C) 2007 Christian Heimes <christian (at) cheimes (dot) de>
+
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 2 of the License, or (at your
+# option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+# more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc., 59
+# Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+"""Directories: Uru game directory and Uru personal data directory
+"""
+__author__ = "Christian Heimes"
+__version__ = "$Id$"
+__revision__ = "$Revision$"
+
+import os
+
+from moul.log import getLogger
+from moul.file.chatlog import ChatlogMover
+from moul.file.chatlog import ChatlogDirectoryView
+from moul.file.plasmalog import PlasmalogZipper
+from moul.file.kiimage import KIImageFixer
+
+LOG = getLogger('moul.file.directory')
+
+class AbstractUruDirectory(object):
+ """Abstract class for an Uru directory
+ """
+ _dirmapping = {}
+
+ def __init__(self, basedir):
+ self._basedir = basedir
+
+ def exists(self):
+ return os.path.isdir(self._basedir)
+
+ def get(self, name):
+ path = self._dirmapping(name)
+ return os.path.join(self._basedir, path)
+
+class UruGameDataDirectory(AbstractUruDirectory):
+ """Uru game directory handler
+
+ An uru game directory contains the launcher, explorer, age files, sound
+ files, localizations and other stuff.
+ """
+ _dirmapping = {
+ 'loc' : 'dat',
+ 'dat' : 'dat',
+ 'sound' : 'sfx'
+ 'soundwav' : 'sfx' + os.sep + 'streamingCache',
+ 'video' : 'avi',
+ }
+
+class UruPersonalDataDirectory(AbstractUruDirectory):
+ """Uru personal data handler
+
+ An uru personal data directory contains per user data like audio and
+ graphics settings, KI shots, avatar images, logs and pyMoul specific
+ data.
+ """
+ _dirmapping = {
+ 'log' : 'Log',
+ 'kiimages' : 'KIimages',
+ 'avatars' : 'Avatars',
+ 'ini' : 'init',
+ 'chatlogs' : 'Chatlogs',
+ 'zipped' : 'ZippedLogs',
+ }
+
Modified: pymoul/trunk/src/moul/file/tests/test_wdysini.py
===================================================================
--- pymoul/trunk/src/moul/file/tests/test_wdysini.py 2007-01-31 15:40:51 UTC (rev 110)
+++ pymoul/trunk/src/moul/file/tests/test_wdysini.py 2007-02-01 00:05:40 UTC (rev 111)
@@ -26,6 +26,8 @@
from StringIO import StringIO
import unittest
from doctest import DocTestSuite
+from tempfile import mkdtemp
+import shutil
from moul.crypt.whatdoyousee import decryptWDYS
from moul.file.wdysini import AudioIni
@@ -45,12 +47,14 @@
def setUp(self):
self.enc_fd = open(self.enc, 'rb')
self.dec_fd = open(self.dec, 'r')
- self.parser = self.parserClass()
-
+ self.tmpdir = mkdtemp()
+ shutil.copy(self.enc, self.tmpdir)
+
def tearDown(self):
self.enc_fd.close()
self.dec_fd.close()
-
+ shutil.rmtree(self.tmpdir)
+
def _compareLines(self, first, second):
flines = first.split('\n')
slines = second.split('\n')
@@ -58,39 +62,58 @@
self.failUnlessEqual(fline, slines[i])
def test_parseString(self):
- p = self.parser
+ p = self.parserClass(self.tmpdir)
data = self.dec_fd.read()
- p.parseString(data)
+ p._parseString(data)
self.failUnless(p._filedata)
self.failIf(p.isChanged())
- newdata = p.writeString()
+ self.failUnless(p.exists())
+ newdata = p._writeString()
self._compareLines(data, newdata)
def test_chars(self):
+ p = self.parserClass(self.tmpdir)
valid = string.ascii_letters + '_. '
data = self.dec_fd.read()
- self.parser.parseString(data)
- for key in self.parser._filedata:
+ p._parseString(data)
+ for key in p._filedata:
for s in key:
self.failUnless(s in valid, s)
def test_cryptparse(self):
- p = self.parser
+ p = self.parserClass(self.tmpdir)
data = self.dec_fd.read()
- p.parseEncFile(self.enc)
- newdata = p.writeString()
+ p._parseEncFile(self.enc)
+ newdata = p._writeString()
self._compareLines(data, newdata)
fdout = StringIO()
- p.writeEncFile(fdout)
-
+ p._writeEncFile(fdout)
+
# round trip
fdout.seek(0)
encdata = decryptWDYS(fdout)
- p.parseString(encdata)
- newdata = p.writeString()
+ p._parseString(encdata)
+ newdata = p._writeString()
self._compareLines(data, newdata)
-
-
+
+ def test_publicapi_read(self):
+ p = self.parserClass(self.tmpdir)
+ p.read()
+ self.failUnless(p.exists())
+ p.write()
+ # TODO: more
+
+ def test_publicapi_create(self):
+ inipath = os.path.join(self.tmpdir, os.path.basename(self.enc))
+ os.unlink(inipath)
+ p = self.parserClass(self.tmpdir)
+ self.failIf(p.exists())
+ p.create()
+ self.failUnless(p.exists())
+ p.write()
+ self.failUnless(p.exists())
+ # TODO: more
+
class AudioIniTest(GenericIniTest):
enc = aud_enc
dec = aud_dec
@@ -102,10 +125,10 @@
parserClass = GraphicsIni
def test_properties(self):
- p = self.parser
+ p = self.parserClass(self.tmpdir)
eq = self.failUnlessEqual
- p.parseEncFile(self.enc)
+ p.read()
eq(p.screenres, 1)
eq(p.windowed, True)
eq(p.antialias, 2)
@@ -116,10 +139,10 @@
eq(p.vsync, False)
def test_property_edit(self):
- p = self.parser
+ p = self.parserClass(self.tmpdir)
eq = self.failUnlessEqual
- p.parseEncFile(self.enc)
+ p.read()
self.failIf(p.isChanged())
p.vsync = True
Modified: pymoul/trunk/src/moul/file/wdysini.py
===================================================================
--- pymoul/trunk/src/moul/file/wdysini.py 2007-01-31 15:40:51 UTC (rev 110)
+++ pymoul/trunk/src/moul/file/wdysini.py 2007-02-01 00:05:40 UTC (rev 111)
@@ -307,46 +307,75 @@
class ConfFile(object):
_options = {}
+ _defaults = {}
_filename = None
- def __init__(self):
+ def __init__(self, path):
+ if not os.path.isdir(path):
+ raise OSError("Directory not found %s" % path)
+ self._fpath = os.path.join(path, self._filename)
self._filedata = {}
self._newdata = {}
self._order = []
- self._fpath = None
-
+ self._opened = False
+
def clear(self):
"""Clear all informations
"""
self._filedata.clear()
self._newdata.clear()
self._order[:] = []
-
+
def reset(self):
"""Reset state of the ini parser
-
+
Copies file data to new data
"""
self._newdata.clear()
self._newdata.update(self._filedata.copy())
-
- def open(self, path):
- """Open encrypted file at 'path'
+
+ def exists(self):
+ """Test if the file exists
"""
- if self._fpath is not None:
+ return os.path.isfile(self._fpath)
+
+ def isChanged(self):
+ """Check if the data was changed
+ """
+ for key, value in self._filedata.items():
+ if value != self._newdata[key]:
+ return True
+ return False
+
+ def read(self):
+ """Open encrypted file at 'path' and parse its data
+ """
+ if self._opened:
raise ValueError("File already open")
- if not os.path.isdir(path):
- raise OSError("Directory not found %s" % path)
- self._fpath = os.path.join(path, self._filename)
- self.parseEncFile(self._fpath)
-
+ self._opened = True
+ self._parseEncFile(self._fpath)
+
+ def create(self):
+ """Create a new file using default values
+ """
+ if self._opened:
+ raise ValueError("File already open")
+ # Create a dummy file
+ fd = open(self._fpath, 'w')
+ fd.write("Created by pyMoul")
+ fd.close()
+ self._opened = True
+ for key, value in self._defaults.items():
+ self._filedata[key] = value
+ self.reset()
+
def write(self):
"""Write data to file
-
+
The write method uses the savest way possible. The old file is backed
up, the new data is written to another file and at last the original
file is replaced with the new file.
-
+
WINDOWS
-------
os.rename() can't replace the file in place under Windows. The final
@@ -355,17 +384,19 @@
orig = self._fpath
if orig is None:
raise ValueError("Full path not set")
+ if not self._opened:
+ raise ValueError("File not opened")
bak = orig + ".bak"
new = orig + ".new"
shutil.copyfile(orig, bak) # make backup
- self.writeEncFile(new) # write new
+ self._writeEncFile(new) # write new
os.unlink(orig) # stupid windows can't perform an atomic rename
os.rename(new, orig) # move new to orig
-
+
# reread the file again
- self.parseEncFile(self._fpath)
-
- def parseEncFile(self, fd_name):
+ self._parseEncFile(self._fpath)
+
+ def _parseEncFile(self, fd_name):
"""Read and parse file (fd or file name)
"""
self.clear()
@@ -379,9 +410,9 @@
data = decryptWDYS(fd)
if close:
fd.close()
- self.parseString(data)
-
- def parseString(self, s):
+ self._parseString(data)
+
+ def _parseString(self, s):
"""Parse string with file contents
@param s: newline seperated file
@@ -414,22 +445,14 @@
raise ValueError(line)
self.reset()
- self.parserDoneHook()
+ self._parserDoneHook()
- def parserDoneHook(self):
+ def _parserDoneHook(self):
"""Hook called after the data is read and parsed
"""
pass
-
- def isChanged(self):
- """Check if the data was changed
- """
- for key, value in self._filedata.items():
- if value != self._newdata[key]:
- return True
- return False
-
- def writeString(self):
+
+ def _writeString(self):
"""Create a string with new file contents
"""
out = []
@@ -448,7 +471,7 @@
out.append('') # new line at EOF
return '\n'.join(out)
- def writeEncFile(self, fd_name):
+ def _writeEncFile(self, fd_name):
"""Write file (fd or file name)
"""
if isinstance(fd_name, basestring):
@@ -457,7 +480,7 @@
else:
fd = fd_name
close = False
- data = self.writeString()
+ data = self._writeString()
encryptWDYS(data, fd)
if close:
fd.close()
@@ -508,9 +531,23 @@
'Audio.SetChannelVolume GUI' : (FloatString, MinMax(0.0, 1.0)), # 0-100%, no ui
# microphon missing -> OS mixer
}
+ _defaults = {
+ 'Audio.Initialize' : BoolString(True),
+ 'Audio.UseEAX' : BoolString(False),
+ 'Audio.SetPriorityCutoff' : 6,
+ 'Audio.MuteAll' : 0, # 0, 1
+ 'Audio.SetChannelVolume SoundFX' : FloatString(1.0),
+ 'Audio.SetChannelVolume BgndMusic' : FloatString(1.0),
+ 'Audio.SetChannelVolume Ambience' : FloatString(1.0),
+ 'Audio.SetChannelVolume NPCVoice' : FloatString(1.0),
+ 'Audio.EnableVoiceRecording' : 1,
+ 'Audio.SetDeviceName' : QuotedString('"Generic Software"'),
+ 'Audio.SetChannelVolume GUI' : FloatString(1.0),
+ # microphon missing -> OS mixer
+ }
_devices = ['"Generic Software"', '"Generic Hardware"']
# plus maybe a custom OpenAL v1.1 device
-
+
def parserDoneHook(self):
"""Hook called after the data is read and parsed
"""
@@ -596,7 +633,21 @@
'Graphics.EnableVSync' : (BoolString, Constrain()), # true/false
'Graphics.Shadow.VisibleDistance' : (FloatString, MinMax(0.0, 1.0)), # 0-1, 0-100%
}
-
+ _defaults = {
+ 'Graphics.Width' : 800,
+ 'Graphics.Height' : 600,
+ 'Graphics.ColorDepth' : 32,
+ 'Graphics.Windowed' : BoolString(False),
+ 'Graphics.AntiAliasAmount' : 0,
+ 'Graphics.AnisotropicLevel' : 1,
+ 'Graphics.TextureQuality' : 1,
+ 'Quality.Level' : 2,
+ 'Graphics.Shadow.Enable' : 1,
+ 'Graphics.EnablePlanarReflections' : 1,
+ 'Graphics.EnableVSync' : BoolString(False),
+ 'Graphics.Shadow.VisibleDistance' : FloatString(0.337126016617),
+ }
+
def _getScreenRes(self):
w = self._newdata['Graphics.Width']
h = self._newdata['Graphics.Height']
Modified: pymoul/trunk/src/moul/qt/mainwindow.py
===================================================================
--- pymoul/trunk/src/moul/qt/mainwindow.py 2007-01-31 15:40:51 UTC (rev 110)
+++ pymoul/trunk/src/moul/qt/mainwindow.py 2007-02-01 00:05:40 UTC (rev 111)
@@ -199,9 +199,9 @@
@qtslot graphicsini_loaded(): notify when a graphics.ini is loaded
"""
inipath = lookupDir('ini')
- self._graphics_ini = gini = GraphicsIni()
+ self._graphics_ini = gini = GraphicsIni(inipath)
try:
- gini.open(inipath)
+ gini.read()
except Exception, msg:
LOG.exception("Something bad happened while parsing the graphics.ini file")
QtGui.QMessageBox.critical(None,
@@ -349,9 +349,9 @@
SIGNAL: audioini_loaded()
"""
inipath = lookupDir('ini')
- self._audio_ini = aini = AudioIni()
+ self._audio_ini = aini = AudioIni(inipath)
try:
- aini.open(inipath)
+ aini.read()
except Exception, msg:
LOG.exception("Something bad happened while parsing the audio.ini file")
QtGui.QMessageBox.critical(None,
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|