Updated eula, new license and updated Hatenatools to the newest version. preparing to add profiles
This commit is contained in:
1 parent
92177ddfb0
commit
23e198ccf0
22 files changed
+1479
-815
No files matched your search
+578
-421
File diff suppressed because it is too large.
Load diff
+166
-36
@@ -1,12 +1,14 @@
|
||||
#NTFT.py by pbsds
|
||||
#Free to use as long as credit is given to pbsds / Peder Bergebakken Sundt
|
||||
#PIL is required to write images to disk
|
||||
#AGPL3 licensed
|
||||
#
|
||||
#Credit:
|
||||
#PIL is required to read and write images to disk
|
||||
#
|
||||
# -The guys behind TiledGGD at https://code.google.com/p/tiledggd/
|
||||
# This sped up the my work a lot
|
||||
import sys
|
||||
#Credits:
|
||||
#
|
||||
# -The guys behind TiledGGD. This sped up my work a lit.
|
||||
# -Jsafive for supplying .ugo files
|
||||
#
|
||||
import sys, os
|
||||
try:
|
||||
import Image
|
||||
hasPIL = True
|
||||
@@ -39,10 +41,28 @@ def DecAsc(dec, length=None, LittleEndian=False):#Converts a decimal into an asc
|
||||
|
||||
if LittleEndian: out.reverse()
|
||||
return "".join(map(chr, out))
|
||||
def clamp(value, min, max):
|
||||
if value > max: return max
|
||||
if value < min: return min
|
||||
return value
|
||||
|
||||
#Class NTFT:
|
||||
#
|
||||
# todo: write documentation
|
||||
# The NTFT image format stores RGB values as 5 bits each: a value between 0 and 31.
|
||||
# It has 1 bit of transparancy, which means its either vidssible or invisible. No gradients.
|
||||
#
|
||||
# How to use:
|
||||
#
|
||||
# Converting to NTFT file:
|
||||
#
|
||||
# image = ReadImage(input_path)
|
||||
# NTFT().SetImage(image).WriteFile(output_path)
|
||||
#
|
||||
# Reading NTFT file:
|
||||
#
|
||||
# ntft = NTFT().ReadFile(input_path, (width, height))
|
||||
# WriteImage(ntft.Image, output_path)
|
||||
#
|
||||
class NTFT:
|
||||
def __init__(self):
|
||||
self.Loaded = False
|
||||
@@ -52,41 +72,89 @@ class NTFT:
|
||||
f.close()
|
||||
return ret
|
||||
def Read(self, data, (w, h)):
|
||||
if w*h*2 <> len(data):
|
||||
print "Invalid size"
|
||||
#the actual stored data is a image with the sizes padded to the nearest power of 2. The image is then clipped out from it.
|
||||
psize = []
|
||||
for i in (w, h):
|
||||
p = 1
|
||||
while 1<<p < i:
|
||||
p += 1
|
||||
psize.append(1<<p)
|
||||
pw, ph = psize
|
||||
|
||||
#check if it fits the file:
|
||||
if pw*ph*2 <> len(data):
|
||||
print "Invalid sizes"
|
||||
return False
|
||||
|
||||
#JUST DO IT!
|
||||
self.Image = [[None for _ in xrange(h)] for _ in xrange(w)]
|
||||
for y in xrange(h):
|
||||
for x in xrange(w):
|
||||
pos = (x + y*w)*2
|
||||
#print pos
|
||||
pos = (x + y*pw)*2
|
||||
byte = AscDec(data[pos:pos+2], True)
|
||||
byte = AscDec(data[pos:pos+2], True)
|
||||
#ARGB1555 -> RGBA8:#require true
|
||||
|
||||
#ARGB1555 -> RGBA8:
|
||||
a = (byte >> 15 ) * 0xFF
|
||||
b = (byte >> 10 & 0x1F) * 0xFF / 0x1F
|
||||
g = (byte >> 5 & 0x1F) * 0xFF / 0x1F
|
||||
r = (byte & 0x1F) * 0xFF / 0x1F
|
||||
# #RGB565 -> RGBA8:
|
||||
# a = 0xFF
|
||||
# r = (byte >> 11 & 0x1F) * 0xFF / 0x1F
|
||||
# g = (byte >> 5 & 0x3F) * 0xFF / 0x3F
|
||||
# b = (byte & 0x1F) * 0xFF / 0x1F
|
||||
#print x, y
|
||||
|
||||
self.Image[x][y] = (r<<24) | (g<<16) | (b<<8) | a#RGBA8
|
||||
|
||||
self.Loaded = True
|
||||
return self
|
||||
def WriteFile(self, path):
|
||||
pass
|
||||
if self.Loaded:
|
||||
f = open(path, "wb")
|
||||
f.write(self.Pack())
|
||||
f.close()
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
def Pack(self):
|
||||
pass
|
||||
if not self.Loaded:
|
||||
return False
|
||||
|
||||
w = len(self.Image[0])
|
||||
h = len(self.Image)
|
||||
|
||||
#the actual stored data is a image with the sizes padded to the nearest power of 2
|
||||
psize = []
|
||||
for i in size:
|
||||
p = 1
|
||||
while 1<<p < i:
|
||||
p += 1
|
||||
padded_size.append(1<<p)
|
||||
|
||||
out = []
|
||||
for y in xrange(psize[1]):
|
||||
for x in xrange(psize[0]):
|
||||
#read
|
||||
c = self.Image[clamp(x, 0, w)][clamp(y, 0, h)]
|
||||
r = c >> 24
|
||||
g = (c >> 16) & 0xFF
|
||||
b = (c >> 8 ) & 0xFF
|
||||
a = c & 0xFF
|
||||
|
||||
#convert
|
||||
a = 1 if a >= 0x80 else 0
|
||||
r = r * 0x1F / 0xFF
|
||||
g = g * 0x1F / 0xFF
|
||||
b = b * 0x1F / 0xFF
|
||||
|
||||
#store
|
||||
out.append(DecAsc((a<<15) | (b<<10) | (g<<5) | r, 2, True))
|
||||
|
||||
return "".join(out)
|
||||
def SetImage(self, Image):
|
||||
self.Image = Image
|
||||
self.Loaded = True
|
||||
return self
|
||||
|
||||
#Function WriteImage:
|
||||
#
|
||||
# Writes a 2D list if uint32 RGBA values as a image files.
|
||||
# Designed to work with PPM().Thumbnail or PPM().GetFrame(n)
|
||||
# Writes a 2D list of uint32 RGBA values as a image files.
|
||||
# Designed to work with NTFT.Image
|
||||
#
|
||||
# This function requires the PIl imaging module
|
||||
def WriteImage(image, outputPath):
|
||||
@@ -104,8 +172,39 @@ def WriteImage(image, outputPath):
|
||||
|
||||
return True
|
||||
|
||||
#Function ReadImage:
|
||||
#
|
||||
# Returns a 2D list of uint32 RGBA values of the image file.
|
||||
# This can be passed into NTFT().SetImage()
|
||||
#
|
||||
# This function requires the PIl imaging module
|
||||
def ReadImage(path):
|
||||
if not hasPIL: return False
|
||||
|
||||
image = Image.open(path)
|
||||
pixeldata = image.getdata()
|
||||
w, h = image.size
|
||||
|
||||
if len(pixeldata[0]) < 4:
|
||||
def Combine((r, g, b)):
|
||||
return (r << 24) | (g << 16) | (b << 8) | 0xFF
|
||||
else:
|
||||
def Combine((r, g, b, a)):
|
||||
return (r << 24) | (g << 16) | (b << 8) | a
|
||||
|
||||
ret = []
|
||||
for x in xrange(w):
|
||||
line = []
|
||||
for y in xrange(h):
|
||||
line.append(Combine(pixeldata[y*w + x]))
|
||||
ret.append(line)
|
||||
|
||||
return ret
|
||||
|
||||
|
||||
|
||||
#testing:
|
||||
# i = NTFT().ReadFile("NTFTtests/kaeru.ntft", (64, 32))
|
||||
# i = NTFT().ReadFile("NTFTtests/kaeru.ntft", (36, 30))
|
||||
# WriteImage(i.Image, "NTFTtests/kaeru.png")
|
||||
|
||||
# i = NTFT().ReadFile("NTFTtests/News.ntft", (32, 32))
|
||||
@@ -114,27 +213,58 @@ def WriteImage(image, outputPath):
|
||||
# i = NTFT().ReadFile("NTFTtests/Special Room.ntft", (32, 32))
|
||||
# WriteImage(i.Image, "NTFTtests/Special Room.png")
|
||||
|
||||
#i = NTFT()
|
||||
#i.Loaded = True
|
||||
#i.Image = ReadImage("NTFTtests/geh.png")
|
||||
#i.WriteFile("NTFTtests/geh.ntft")
|
||||
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
print " == NTFT.py =="
|
||||
print " == by pbsds =="
|
||||
print " == v0.05 =="
|
||||
print " == v0.70 =="
|
||||
print
|
||||
|
||||
if len(sys.argv) < 4:
|
||||
if len(sys.argv) < 3:
|
||||
print "Usage:"
|
||||
print " NTFT.py <input> <output> <width> <height>"
|
||||
print " NTFT.py <input> [<output> [<width> <height>]]"
|
||||
print ""
|
||||
print "The NTFT file contain only the colordata, so it's up to the user to find and"
|
||||
print "store the resolution of the images."
|
||||
print "32x32 is the normal size for button icons in UGO files."
|
||||
print "Can convert a NTFT to PNG or the other way around."
|
||||
print "if <output> isn't spesified it will be set to <input> with an another extention"
|
||||
print ""
|
||||
print "The NTFT file contain only the colordata, so it's up to the user to find or"
|
||||
print "store the resolution of the image. <width> and <height> is required"
|
||||
print "to convert a NTFT file to a image."
|
||||
print "32x32 is the normal resolution for button icons in UGO files."
|
||||
sys.exit()
|
||||
|
||||
input = sys.argv[1]
|
||||
output = sys.argv[2]
|
||||
width = int(sys.argv[3])
|
||||
height = int(sys.argv[4])
|
||||
Encode = True#if false it'll decode
|
||||
|
||||
if input[-4:].lower == "ntft" or len(sys.argv) >= 5:
|
||||
Encode = False
|
||||
|
||||
if len(sys.argv) >= 3:
|
||||
output = sys.argv[2]
|
||||
|
||||
if len(sys.argv) >= 5:
|
||||
if (not sys.argv[3].isdigit()) or (not sys.argv[4].isdigit()):
|
||||
print "Invalid sizes"
|
||||
sys.exit()
|
||||
width = int(sys.argv[3])
|
||||
height = int(sys.argv[4])
|
||||
else:
|
||||
width, height = None, None
|
||||
else:
|
||||
output = ".".join(input.split(".")[:-1]) + (".ntft" if Encode else ".png")
|
||||
|
||||
print "Converting..."
|
||||
WriteImage(NTFT().ReadFile(input, (width, height)).Image, output)
|
||||
print "Done!"
|
||||
|
||||
if Encode:
|
||||
i = NTFT()
|
||||
i.Loaded = True
|
||||
i.Image = ReadImage("NTFTtests/geh.png")
|
||||
i.WriteFile(output)
|
||||
else:
|
||||
WriteImage(NTFT().ReadFile(input, (width, height)).Image, output)
|
||||
print "Done!"
|
||||
+44
-44
@@ -1,13 +1,14 @@
|
||||
#PPM.py by pbsds for python 2.7
|
||||
#Free to use. Publicated modifications must give credit to pbsds / Peder Bergebakken Sundt
|
||||
#PIL is required to write frames and thumbnails to disk
|
||||
#AGPL3 licensed
|
||||
#
|
||||
#PIL is required to write images to disk
|
||||
#
|
||||
#Credits:
|
||||
#
|
||||
# -Steven for most of the documentation on DSiBrew and his frame decoding example on his talkpage
|
||||
# -Remark for help on the 8x8 tiling on the preview image.
|
||||
# -Austin Burk and Jsafive for supplying .tmb files
|
||||
|
||||
# -Jsafive for supplying .tmb files
|
||||
#
|
||||
import sys, wave#needs os and time aswell
|
||||
try:
|
||||
import Image
|
||||
@@ -562,7 +563,7 @@ def WriteImage(image, outputPath):
|
||||
return True
|
||||
|
||||
#this is just for experimenting with sound decoding:
|
||||
#not even close to being finished
|
||||
#not even remotely close to being finished
|
||||
def DecodeSound(outputpath, data):
|
||||
f = wave.open(outputpath, "wb")
|
||||
f.setnchannels(1)
|
||||
@@ -580,35 +581,34 @@ def DecodeSound(outputpath, data):
|
||||
f.writeframes(DecAsc(i2<<12, 2, True)*4)
|
||||
f.close()
|
||||
|
||||
#for testing during development:
|
||||
if 1 == 2:
|
||||
p = PPM()
|
||||
print "loading ppm..."
|
||||
p.ReadFile("PPMtests/test.ppm", (1, 1, 1))
|
||||
|
||||
print str(p.OriginalAuthorName), str(p.OriginalAuthorID)
|
||||
print str(p.EditorAuthorName), str(p.EditorAuthorID)
|
||||
|
||||
print "Dumping Thumbnail..."
|
||||
WriteImage(p.Thumbnail, "thumbnail.png")
|
||||
|
||||
print "Dumping frames..."
|
||||
for i in xrange(p.FrameCount):
|
||||
WriteImage(p.GetFrame(i), "frames/frame %i.png" % i)
|
||||
|
||||
print "Dumping raw sounds..."
|
||||
for i, data in enumerate(p.SoundData):
|
||||
f = open("sound %i.bin" % i, "wb")
|
||||
f.write(data)
|
||||
f.close()
|
||||
|
||||
print "Extracting sounds...."
|
||||
for i, d in enumerate(p.SoundData): DecodeSound("out_%i.wav"%i, d)
|
||||
#testing:
|
||||
# p = PPM()
|
||||
# print "loading ppm..."
|
||||
# p.ReadFile("PPMtests/test.ppm", (1, 1, 1))
|
||||
|
||||
# print str(p.OriginalAuthorName), str(p.OriginalAuthorID)
|
||||
# print str(p.EditorAuthorName), str(p.EditorAuthorID)
|
||||
|
||||
# print "Dumping Thumbnail..."
|
||||
# WriteImage(p.Thumbnail, "thumbnail.png")
|
||||
|
||||
# print "Dumping frames..."
|
||||
# for i in xrange(p.FrameCount):
|
||||
# WriteImage(p.GetFrame(i), "frames/frame %i.png" % i)
|
||||
|
||||
# print "Dumping raw sounds..."
|
||||
# for i, data in enumerate(p.SoundData):
|
||||
# f = open("sound %i.bin" % i, "wb")
|
||||
# f.write(data)
|
||||
# f.close()
|
||||
|
||||
# print "Extracting sounds...."
|
||||
# for i, d in enumerate(p.SoundData): DecodeSound("out_%i.wav"%i, d)
|
||||
|
||||
if __name__ == '__main__':
|
||||
print " == PPM.py =="
|
||||
print " == by pbsds =="
|
||||
print " == v1.03 =="
|
||||
print " == v1.05 =="
|
||||
print
|
||||
|
||||
if len(sys.argv) < 3:
|
||||
@@ -616,16 +616,16 @@ if __name__ == '__main__':
|
||||
print " PPM.py <Mode> <Input> [<Output>] [<Frame>]"
|
||||
print ""
|
||||
print " <Mode>:"
|
||||
print " 0: Extracts the thumbnail to the file <Output>"
|
||||
print " 1: Extracts the frame(s) to <Output>"
|
||||
print " 2: Dumps the raw sound data files to the folder <Output>"
|
||||
print " 3: Same as mode 2, but will also dump the experimentally decoded"
|
||||
print " sounds."
|
||||
print " 4: Prints out the metadata. Can also write it to <output> which also"
|
||||
print " supports unicode charactes."
|
||||
print " Mode 0 and 4 supports TMB files aswell"
|
||||
print " -t: Extracts the thumbnail to the file <Output>"
|
||||
print " -f: Extracts the frame(s) to <Output>"
|
||||
print " -s: Dumps the raw sound data files to the folder <Output>"
|
||||
print " -S: Same as mode 2, but will also dump the experimentally decoded"
|
||||
print " sounds."
|
||||
print " -m: Prints out the metadata. Can also write it to <output> which also"
|
||||
print " supports unicode charactes."
|
||||
print " Mode -t and -m supports TMB files aswell"
|
||||
print " <Frame>"
|
||||
print " Only used in mode 1"
|
||||
print " Only used in mode -f"
|
||||
print " Set this to the exact frame you want to extract(starting at 1) and it"
|
||||
print " will be saved as a file to <Output>."
|
||||
print " If not specified, it will extract all frames to the folder <Output>"
|
||||
@@ -634,7 +634,7 @@ if __name__ == '__main__':
|
||||
|
||||
import os, time
|
||||
|
||||
if sys.argv[1] == "0":
|
||||
if sys.argv[1] == "-t":
|
||||
print "Reading the flipnote file...",
|
||||
if not os.path.isfile(sys.argv[2]):
|
||||
print "Error!\nSpecified file doesn't exist!"
|
||||
@@ -649,7 +649,7 @@ if __name__ == '__main__':
|
||||
print "Dumping the thumbnail...",
|
||||
WriteImage(flipnote.GetThumbnail(), sys.argv[3])
|
||||
print "Done!"
|
||||
elif sys.argv[1] == "1":
|
||||
elif sys.argv[1] == "-f":
|
||||
if len(sys.argv) < 4:
|
||||
print "Error!"
|
||||
print "<Output> not specified!"
|
||||
@@ -689,7 +689,7 @@ if __name__ == '__main__':
|
||||
print "Dumping frame #%i..." % int(sys.argv[4]),
|
||||
WriteImage(flipnote.GetFrame(int(sys.argv[4])-1), sys.argv[3])
|
||||
print "Done!"
|
||||
elif sys.argv[1] in "23":
|
||||
elif sys.argv[1] in ("-s", "-S"):
|
||||
if len(sys.argv) < 4:
|
||||
print "Error!"
|
||||
print "<Output> not specified!"
|
||||
@@ -716,7 +716,7 @@ if __name__ == '__main__':
|
||||
f.close()
|
||||
print "Done!"
|
||||
|
||||
if sys.argv[1] == "3":
|
||||
if sys.argv[1] == "-S":
|
||||
print "Dumping the decoded sound data...",
|
||||
for i, data in enumerate(flipnote.SoundData):
|
||||
DecodeSound(os.path.join(sys.argv[3], ("BGM decoded.wav", "SFX1 decoded.wav", "SFX2 decoded.wav", "SFX3 decoded.wav")[i]), data)
|
||||
@@ -728,7 +728,7 @@ if __name__ == '__main__':
|
||||
f.write("Frame %i:%s%s%s\n" % (i, " SFX1"*s1, " SFX2"*s2, " SFX3"*s3))
|
||||
f.close()
|
||||
print "Done!"
|
||||
elif sys.argv[1] == "4":
|
||||
elif sys.argv[1] == "-m":
|
||||
epoch = time.mktime(time.struct_time([2000, 1, 1, 0, 0, 0, 5, 1, -1]))
|
||||
|
||||
if not os.path.isfile(sys.argv[2]):
|
||||
|
||||
+11
-7
@@ -3,9 +3,9 @@
|
||||
== aka Peder Bergebakken Sundt ==
|
||||
|
||||
--VERSIONS--
|
||||
PPM.py: v1.03
|
||||
UGO.py: v0.09
|
||||
NTFT.py: v0.05
|
||||
PPM.py: v1.05
|
||||
UGO.py: v0.92
|
||||
NTFT.py: v0.70
|
||||
|
||||
--DESCRIPTION--
|
||||
PPM.py can read the metadata, thumbnail, frames and the sound of Flipnote Studio files: .ppm
|
||||
@@ -20,11 +20,15 @@ Warning, it's still in a very crude state. Error will occour
|
||||
These are all tested and written in python 2.7
|
||||
These are all designed to be usable both as python modules and as stand alone applications.
|
||||
|
||||
--LICENCE--
|
||||
Free to use.
|
||||
They are free to modify as you wish as long you give credit to me, pbsds / Peder Bergebakken Sundt
|
||||
--DOCUMENTATION--
|
||||
Documentation on the formats can be found here:
|
||||
https://github.com/pbsds/hatena-server/wiki
|
||||
|
||||
--LICENSE--
|
||||
This is licensed by AGPL3
|
||||
See License.txt
|
||||
|
||||
--CREDIT--
|
||||
-Steven for most of the documentation on DSiBrew and his frame decoding example on his talkpage
|
||||
-Remark for helping me understanding the 8x8 tiling on the preview images.
|
||||
-Austin Burk and Jsafive for supplying .tmb and .ugo files
|
||||
-JSAfive for supplying .tmb and .ugo files
|
||||
+87
-35
@@ -1,6 +1,18 @@
|
||||
#UGO.py by pbsds
|
||||
#AGPL3 licensed
|
||||
#
|
||||
#This class reads and writes UGO files.
|
||||
#cal also export and import it in the xml format
|
||||
#Extended functionality added by PPM.py from http://pbsds.net/projects/ppm
|
||||
#It can also export and import it in a xml format
|
||||
#Extended functionality added by PPM.py
|
||||
#
|
||||
#Credits:
|
||||
#
|
||||
# -Jsafive for supplying .ugo files
|
||||
#
|
||||
#Note:
|
||||
# The current implentation can possibly mess up the files stored in Section #2, but will do for most needs
|
||||
# Next version will probably bring a big change in the ugoxml format
|
||||
#
|
||||
import sys, os
|
||||
from base64 import b64encode, b64decode
|
||||
import xml.etree.ElementTree as ET
|
||||
@@ -10,7 +22,6 @@ try:
|
||||
HasPPM = True
|
||||
except ImportError:
|
||||
HasPPM = False
|
||||
|
||||
|
||||
#helpers:
|
||||
def AscDec(ascii, LittleEndian=False):#Converts a ascii string into a decimal
|
||||
@@ -39,7 +50,7 @@ def DecAsc(dec, length=None, LittleEndian=False):#Converts a decimal into an asc
|
||||
return "".join(map(chr, out))
|
||||
def zipalign(length, r=4):
|
||||
return length + (4 - length % r) if length % r else length
|
||||
def indentXML(elem, level=0):#borrowed from: http://effbot.org/zone/element-lib.htm#prettyprint
|
||||
def indentXML(elem, level=0):#"borrowed" from: http://effbot.org/zone/element-lib.htm#prettyprint
|
||||
i = "\n" + level*"\t"
|
||||
if len(elem):
|
||||
if not elem.text or not elem.text.strip():
|
||||
@@ -97,8 +108,13 @@ class UGO:
|
||||
if Sections >= 2:
|
||||
ExtraData = data[zipalign(headerlength+self.TableLength) : zipalign(headerlength+self.TableLength)+self.ExtraLength]
|
||||
|
||||
#Read data:
|
||||
#Parse data:
|
||||
self.Items = []
|
||||
|
||||
#todo: implement this:
|
||||
self.Files = []#[i] = (filename, filecontent)
|
||||
#see todo.txt
|
||||
|
||||
pos = 0#Extra Data position
|
||||
tmbcount = 1#used if HasPPM is False
|
||||
ntftcount = 1#used if no label
|
||||
@@ -120,7 +136,7 @@ class UGO:
|
||||
self.Items.append(("topscreen text", labels, num))
|
||||
continue
|
||||
elif type == 2:#catogories(like "reccomended" and "new flipnotes" and "most popular")
|
||||
#this one may change greatly depending on what layout is set in type==0
|
||||
#this one may visually change greatly depending on what layout is set in type==0
|
||||
|
||||
link = i[1]
|
||||
label = b64decode(i[2]).decode("UTF-16LE")
|
||||
@@ -128,8 +144,12 @@ class UGO:
|
||||
|
||||
self.Items.append(("category", link, label, selected))
|
||||
continue
|
||||
elif type == 3:#POST button? "Post Flipnote"
|
||||
pass
|
||||
elif type == 3:#POST button/link to POST form. "Post Flipnote" uses this
|
||||
link = i[1]
|
||||
label = b64decode(i[2]).decode("UTF-16LE")
|
||||
|
||||
self.Items.append(("post", link, label))
|
||||
continue
|
||||
elif type == 4:#Button
|
||||
link = i[1]
|
||||
trait = int(i[2])
|
||||
@@ -250,9 +270,13 @@ class UGO:
|
||||
selected = str(1*selected)
|
||||
|
||||
TableOfContents.append("\t".join(("2", link, label, selected)))
|
||||
elif i[0] == "post":#not yet implented
|
||||
pass
|
||||
elif i[0] == "button":
|
||||
elif i[0] == "post":#3
|
||||
link, label = i[1:]
|
||||
|
||||
label = b64encode(label.encode("UTF-16LE"))
|
||||
|
||||
TableOfContents.append("\t".join(("3", link, label)))
|
||||
elif i[0] == "button":#4
|
||||
trait, label, link, other, file = i[1:]
|
||||
|
||||
trait = str(trait)
|
||||
@@ -297,7 +321,7 @@ class UGO:
|
||||
|
||||
for i in self.Items:
|
||||
if i[0] == "unknown":
|
||||
elem = ET.SubElement(ugo_xml, "unknown", type=i[1][0])
|
||||
elem = ET.SubElement(ugo_xml, "raw", type=i[1][0])
|
||||
for value in i[1][1:]:
|
||||
ET.SubElement(elem, "value").text = value
|
||||
continue
|
||||
@@ -323,7 +347,11 @@ class UGO:
|
||||
ET.SubElement(elem, "address").text = link
|
||||
ET.SubElement(elem, "selected").text = str(selected).lower()
|
||||
elif i[0] == "post":#3
|
||||
pass#not yet implented/parsed
|
||||
elem = ET.SubElement(ugo_xml, "post")
|
||||
link, label = i[1:]
|
||||
|
||||
ET.SubElement(elem, "label").text = label
|
||||
ET.SubElement(elem, "address").text = link
|
||||
elif i[0] == "button":#4
|
||||
elem = ET.SubElement(ugo_xml, "button")
|
||||
trait, label, link, other, file = i[1:]
|
||||
@@ -361,9 +389,9 @@ class UGO:
|
||||
|
||||
Items = []
|
||||
for elem in ugo_xml:
|
||||
if elem.tag == "unknown":
|
||||
if elem.tag == "raw":
|
||||
if "type" not in elem.attrib:
|
||||
if not silent: print "Invalid formatting. <unknown> without \"type\" attribute"
|
||||
if not silent: print "Invalid formatting. <raw> without \"type\" attribute"
|
||||
return False
|
||||
values = [elem.attrib["type"]]
|
||||
for value in elem:
|
||||
@@ -438,8 +466,27 @@ class UGO:
|
||||
selected = value.text[0].lower() in "t1"
|
||||
|
||||
Items.append(("category", link, label, selected))
|
||||
elif elem.tag == "post":#3 not yet implented
|
||||
pass
|
||||
elif elem.tag == "post":#3
|
||||
label = None
|
||||
link = None
|
||||
|
||||
for value in elem:
|
||||
if value.tag == "label":
|
||||
if isinstance(label, str):
|
||||
if not silent: print "Invalid formatting. Multible <label> within <post>"
|
||||
return False
|
||||
label = value.text if value.text else ""
|
||||
elif value.tag == "address":
|
||||
if isinstance(link, str):
|
||||
if not silent: print "Invalid formatting. Multible <address> within <post>"
|
||||
return False
|
||||
link = value.text if value.text else ""
|
||||
|
||||
if None in (link, label):
|
||||
if not silent: print "Invalid formatting. <button> lacks either a <address> or <label>"
|
||||
return False
|
||||
|
||||
Items.append(("post", link, label))
|
||||
elif elem.tag == "button":#4
|
||||
trait = None#todo: add names
|
||||
label = None
|
||||
@@ -504,12 +551,12 @@ class UGO:
|
||||
if __name__ == "__main__":
|
||||
print " == UGO.py =="
|
||||
print " == by pbsds =="
|
||||
print " == v0.90 =="
|
||||
print " == v0.92 =="
|
||||
print
|
||||
|
||||
if len(sys.argv) < 3:
|
||||
if len(sys.argv) < 2:
|
||||
print "Usage:"
|
||||
print " UGO.py <mode> <input> [<output> [<foldername>]]"
|
||||
print " UGO.py [<mode>] <input> [<output> [<foldername>]]"
|
||||
print ""
|
||||
print " <Mode>:"
|
||||
print " -d: Converts the UGO file in <input> to a UGOXML file with the same"
|
||||
@@ -519,12 +566,28 @@ if __name__ == "__main__":
|
||||
print " <foldername> is relative to the XML."
|
||||
print " -e: Converts the UGOXML file in <input> to a UGO file with the same"
|
||||
print " name, unless <output> is specified."
|
||||
print " If mode is not specified, it will try to find out for itself"
|
||||
sys.exit()
|
||||
|
||||
mode = sys.argv[1]
|
||||
if mode not in ("-d", "-e"):
|
||||
print "Invalid <mode> given"
|
||||
sys.exit()
|
||||
if os.path.exists(mode):#the mode is actually the file
|
||||
f = open(mode, "rb")
|
||||
magic = f.read(4)
|
||||
f.close()
|
||||
|
||||
if magic == "UGAR":
|
||||
mode = "-d"
|
||||
print "No mode specified. UGO -> UGOXML chosen"
|
||||
else:
|
||||
mode = "-e"
|
||||
print "No mode specified. UGOXML -> UGO chosen"
|
||||
|
||||
sys.argv.insert(1, mode)
|
||||
else:
|
||||
print "Invalid <mode> given!"
|
||||
sys.exit()
|
||||
|
||||
if mode == "-d":
|
||||
input = sys.argv[2]
|
||||
output = sys.argv[3] if len(sys.argv) >= 4 else sys.argv[2]+"xml"
|
||||
@@ -549,7 +612,7 @@ if __name__ == "__main__":
|
||||
try:
|
||||
ugo = UGO().ReadXML(input, False)
|
||||
except EL.ParseError:
|
||||
print "Error!\nThe given file is not in the XML format"
|
||||
print "Error!\nThe given file is not in the XML format!"
|
||||
ugo = False
|
||||
if not ugo:
|
||||
#it prints sufficient errormessages
|
||||
@@ -559,15 +622,4 @@ if __name__ == "__main__":
|
||||
|
||||
print "Writing UGO..."
|
||||
ugo.WriteFile(output)
|
||||
print "Done"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
print "Done"
|
||||
Reference in new issue
Block a user
