From The Mana World
(→‎How to create this page: Added warning about scripts being out of date)
(Archived outdated content (#1,) removed many scripts and updated the itemdbtowiki script)
Line 1: Line 1:
==Problems==
==Archives==
=== Prices are off ===


Right now, the prices in the autogenerated list are not always right. For example an arrow sells for 2 GP, not 1, i believe that is because the item_db in the CVS is not the one actually currently used.
Archives of outdated information from this talk page are here:
-Ados, 2005-07-20
* [[Talk:Item_reference/Archive_1|Archive #1]]


==Problems==


Arrow and some other prices manually fixed --xand
===itemdbtowiki does not take enough arguments===
In the future, itemdbtowiki should be modified to take some extra arguments from the command line, such as 'image_path', 'checkimagesonwiki', and perhaps the username and password.


== How to create this page ==
== How to create this page ==
If you just want to add a few images or change the appearance of the page. You can jump directly to step 5.
I have completed the new new script to recreate this page, please leave me a note if you find any problems. It is now capable of uploading new images to the wiki! --[[User:Hype0|Hype0]] 02:42, 3 September 2007 (CEST)  
 
'''Warning:''' These scripts are out of date.  I am working on a new script, [[User:Hype0|see it on my talk page.]] It will (and already does) auto-upload images with proper descriptions.
 
===Step 1===
First, create individual item images by using the '''tilesplit''' tool. It uses the PIL (Python Image Library), so you possibly have to install that first. The usage is
<pre>
pngsplit <startid> <endid> <items.png>.
</pre>
for example, like used in the creation of the original page. But obviously you can just generate the new items now:
<pre>
./tilesplit 1 73 /home/user/_code/tmw/data/graphics/sprites/items.png
</pre>
This means the IDs used in the client data/items.xml from the client, which begin at 1. The items.png can be found in data/graphics/sprites/ and contains 10 items in a row, which makes it relatively easy to determine the id numbers you want. The program will then copy the files into a subdirectory pics (or pics2, pics3 ..., if that directory already exists).
 
===Step 2===
Step two is to upload the images to [http://www.imageshack.us imageshack], or a similiar provider of your choice. I really, with all of my heart, wish I'd know how to write a tool that believably pretends to be a popular webbrowser. But as long as such a thing does not exist, you've got to do it by hand. While uploading, copy the urls as a linebreak-seperated listing into a textfile. Like so:
<pre>
http://img296.imageshack.us/img296/2363/013nw.png
http://img167.imageshack.us/img167/6766/025ia.png
http://img179.imageshack.us/img179/9046/031oj.png
http://img301.imageshack.us/img301/6505/041gt.png
http://img207.imageshack.us/img207/2556/059or.png
</pre>


===Step 3===
You can run '''itemdbtowiki''' to generate the wiki page. The usage is:
You can now optionally convert that list to html code with ''' urlstohtml ''' and compare it with the original items.png to figure out whether you did it all right. Like this:
<pre>
cat urlist | urlstohtml > foo.html
</pre>
 
===Step 4===
Now it's time to modify the imageurl list in the code of '''itemdbtowiki'''. You can autogenerate the updates to the list ''imageurls'' by running '''urlstopython''' like so:
<pre>
cat urllist | urlstopython <startid>
</pre>
itemdbtowiki uses the IDs from items.xml, which (as i said before) start with 1. If your urllist, started with, let's say, the image 74. You'd call
<pre>
> cat urllist | urlstopython 74
    "http://img296.imageshack.us/img296/2363/743nw.png",      #  74
    "http://img167.imageshack.us/img167/6766/75ia.png",        #  75
    "http://img179.imageshack.us/img179/9046/761oj.png",      #  76
    "http://img301.imageshack.us/img301/6505/771gt.png",      #  77
    "http://img207.imageshack.us/img207/2556/789or.png",      #  78
[...]
</pre>
 
===Step 5===
 
Now you can run '''itemdbtowiki''' to generate the wiki page. The usage is:
<pre>
<pre>
itemdbtowiki <item_db.txt> <items.xml> > wikipage.txt
itemdbtowiki <item_db.txt> <items.xml> > wikipage.txt
Line 64: Line 18:
If run without any arguments, it'll look for item_db.txt and items.xml in the current directory.
If run without any arguments, it'll look for item_db.txt and items.xml in the current directory.


==Python-Tools==
To upload new images to the wiki automatically, 'checkimagesonwiki' in the file to 1 and set a corresponding valid 'wikiuser' and 'wikipassword' as well as set the 'image_path' to be correct (these are all parameters at the start of the script.)
All these tools are subject to the GNU General Public License.


===tilesplit===
'''Warning:''' if you choose to upload images, authentication will be done in plaintext, which is exactly what happens if you log in over http:// anyway... just thought you might like a reminder.
<pre>
#!/usr/bin/python


import sys, os, math
==Python-Tools==
import Image
import httplib, urllib,mimetools
import MimeWriter, StringIO


def inttostr_zero(i, count):
===itemdbtowiki===
    s = "%d" % i
    while len(s) < count:
        s = "0"+s
    return s
 
def getimgdir():
    if not os.path.exists('pics'):
        os.mkdir('pics')
        return 'pics'
    else:
        i = 2
        while os.path.exists('pics%d' % i):
            i +=1
        os.mkdir('pics%d' % i)
        return 'pics%d' % i
 
 
startindex = int(sys.argv[1])
endindex = int(sys.argv[2])
nlength = math.log10(endindex)
img = Image.open(sys.argv[3])
i = startindex-1
imgdir = getimgdir();
while i < endindex:
    cropbox =  ( (i % 10)*32, (i / 10)*32, (i % 10)*32+32, (i / 10)*32+32 )
    region = img.crop(cropbox)
    region.save("%s/%s.png" % (imgdir, inttostr_zero(i+1, nlength) ) )
    i = i + 1
</pre>
 
===urlstohtml===
<pre>
<pre>
#!/usr/bin/python
#!/usr/bin/python
import sys
#Licensed under GNU General Public License


sys.stdout.write("<html>\n<body>\n")
import sys, os, popen2;
i = 0
import xml.parsers.expat
for url in sys.stdin:
    if len(url) > 5:
        sys.stdout.write('<img src="%s">' % url[:-1])
        if i < 9:
            i += 1
        else:
            sys.stdout.write('\n')
            i = 0
sys.stdout.write("\n</body>\n</html>\n")
</pre>
 
===urlstopython===
<pre>
#!/usr/bin/python
import sys


firstskip = 0
debug=0
space = ""
checkimagesonwiki=0
commentpos = 55
#wikiuser="Hype0"
#wikipassword="password"
image_path="/usr/home/dex/src/themanaworld/tmw/trunk/data/graphics/items"


if len(sys.argv) == 1:
health_titles = ["Image","Name","ID","HP Bonus","SP Bonus",
    i = 0
                "Price<BR />BUY/Sell","Weight","Description"]
    sys.stdout.write('imageurls = [\n')
status_titles = ["Image","Name","ID","Spell name","Parameter 1","Parameter 2",
    sys.stdout.write('# The index represents the imageID from the items.xml of the client.\n')
                "Price<BR />BUY/Sell","Weight","Description"]
    sys.stdout.write('    ""')
weapon_titles = [" Image","Name","ID","Damage<BR />(Range)",
else:
                "Price<BR />BUY/Sell","Weight","Description"]
    i = int(sys.argv[1])-1
armor_titles = ["Image", "Name", "ID", "Defense",  
    firstskip = 1
              "Price<BR />BUY/Sell", "Weight","Description"]
    sys.stdout.write('    ')
other_titles = ["Image","Name","ID","Price<BR />BUY/Sell",
 
                "Weight","Description "]
for url in sys.stdin:
    if len(url) > 5:
        #if not commentpos: commentpos = len(url) + 5
        if firstskip:
            firstskip = 0
            sys.stdout.write('"%s"' % (url[:-1]))
        else:
            sys.stdout.write(', %s #%5d\n    "%s"' % (space,i,url[:-1]))
        space = " " * (commentpos-(len(url)))
        i += 1
 
sys.stdout.write('  %s #%5d\n' % (space,i))
sys.stdout.write(']\n')
</pre>
 
===itemdbtowiki===
<pre>
#!/usr/bin/python
#Licensed under GNU General Public License


import sys, os;
import xml.parsers.expat


imageurls = [
imageurls = [
# The index represents the imageID from the items.xml of the client.
# The index represents the imageID from the items.xml of the client.
     "",  #    0
     "",  #    0
    "http://img296.imageshack.us/img296/2363/013nw.png",      #    1
    "http://img167.imageshack.us/img167/6766/025ia.png",      #    2
    "http://img179.imageshack.us/img179/9046/031oj.png",      #    3
    "http://img301.imageshack.us/img301/6505/041gt.png",      #    4
    "http://img207.imageshack.us/img207/2556/059or.png",      #    5
    "http://img229.imageshack.us/img229/2586/066zf.png",      #    6
    "http://img236.imageshack.us/img236/2425/077ed.png",      #    7
    "http://img154.imageshack.us/img154/8776/088cu.png",      #    8
    "http://img292.imageshack.us/img292/765/096cx.png",        #    9
    "http://img296.imageshack.us/img296/4291/103ku.png",      #  10
    "http://img265.imageshack.us/img265/4149/119ml.png",      #  11
    "http://img296.imageshack.us/img296/5246/125wt.png",      #  12
    "http://img248.imageshack.us/img248/6633/132dg.png",      #  13
    "http://img254.imageshack.us/img254/6427/149pm.png",      #  14
    "http://img279.imageshack.us/img279/2362/155sr.png",      #  15
    "http://img116.imageshack.us/img116/4408/167sb.png",      #  16
    "http://img139.imageshack.us/img139/6189/173ut.png",      #  17
    "http://img223.imageshack.us/img223/1794/187xp.png",      #  18
    "http://img229.imageshack.us/img229/1659/195yc.png",      #  19
    "http://img239.imageshack.us/img239/622/205at.png",        #  20
    "http://img153.imageshack.us/img153/1839/219lz.png",      #  21
    "http://img296.imageshack.us/img296/2636/228yi.png",      #  22
    "http://img248.imageshack.us/img248/53/239uu.png",        #  23
    "http://img254.imageshack.us/img254/4431/242qj.png",      #  24
    "http://img279.imageshack.us/img279/1489/254er.png",      #  25
    "http://img116.imageshack.us/img116/9810/269ig.png",      #  26
    "http://img139.imageshack.us/img139/5177/270mi.png",      #  27
    "http://img223.imageshack.us/img223/8136/281bl.png",      #  28
    "http://img229.imageshack.us/img229/6661/297cx.png",      #  29
    "http://img239.imageshack.us/img239/5787/304xp.png",      #  30
    "http://img301.imageshack.us/img301/1121/311an.png",      #  31
    "http://img52.imageshack.us/img52/7388/324fk.png",        #  32
    "http://img141.imageshack.us/img141/9527/336nu.png",      #  33
    "http://img100.imageshack.us/img100/7990/349zk.png",      #  34
    "http://img87.imageshack.us/img87/3489/355nw.png",        #  35
    "http://img151.imageshack.us/img151/5561/365gf.png",      #  36
    "http://img91.imageshack.us/img91/955/370ql.png",          #  37
    "http://img157.imageshack.us/img157/3830/387ay.png",      #  38
    "http://img32.imageshack.us/img32/2695/391hf.png",        #  39
    "http://img112.imageshack.us/img112/9297/400la.png",      #  40
    "http://img301.imageshack.us/img301/5387/412uz.png",      #  41
     "http://img52.imageshack.us/img52/3072/423xc.png",        #  42
     "http://img52.imageshack.us/img52/3072/423xc.png",        #  42
     "http://img187.imageshack.us/img187/2963/434dc.png",      #  43
     "http://img187.imageshack.us/img187/2963/434dc.png",      #  43
Line 234: Line 76:
     "http://img187.imageshack.us/img187/6240/637ju.png",      #  63
     "http://img187.imageshack.us/img187/6240/637ju.png",      #  63
     "http://img275.imageshack.us/img275/9440/648zq.png",      #  64
     "http://img275.imageshack.us/img275/9440/648zq.png",      #  64
    "http://img169.imageshack.us/img169/8508/655is.png",      #  65
    "http://img195.imageshack.us/img195/9153/660zq.png",      #  66
     "http://img288.imageshack.us/img288/8669/673xe.png",      #  67
     "http://img288.imageshack.us/img288/8669/673xe.png",      #  67
    "http://img242.imageshack.us/img242/3228/688wv.png",      #  68
     "http://img214.imageshack.us/img214/8675/693wb.png",      #  69
     "http://img214.imageshack.us/img214/8675/693wb.png",      #  69
    "http://img98.imageshack.us/img98/774/703wa.png",          #  70
    "http://img157.imageshack.us/img157/7590/717em.png",      #  71
    "http://img299.imageshack.us/img299/4237/721eu.png",      #  72
    "http://img246.imageshack.us/img246/8151/731cd.png"        #  73
]
]


Line 319: Line 154:
     objects = []
     objects = []
     for line in file:
     for line in file:
         s = line[0:line.find('//')].strip()
         s = line[0:line.find('//')].strip().replace('\t','')
         if s:
         if s:
             #Replace commas inbetween {} with |, so we can use split
             #Replace commas inbetween {} with |, so we can use split
Line 335: Line 170:


             values = sout.split(',')
             values = sout.split(',')
            if line[0] == '#':
                if debug:
                    log.append("FOUND COMMENT LINE: %s" % str(values))
                continue
             if (len(values) != 19):
             if (len(values) != 19):
                 log.append("item_db: Warning, item-line with ID %s has %d values instead of 19" % (values[0], len(values)))
                 log.append("item_db: Warning, item-line with ID %s has %d values instead of 19" % (values[0], len(values)))
                if debug:
                    log.append("  line was %s" % str(values))
                 while (len(values) < 19):
                 while (len(values) < 19):
                     values.append('')
                     values.append('')
Line 377: Line 218:
     term = "/>"
     term = "/>"
     attrs = ["id", "image", "art", "name", "description", "type", "weight", "slot"]
     attrs = ["id", "image", "art", "name", "description", "type", "weight", "slot"]
     intattrs = ["id", "image", "art", "type", "weight", "slot"]
     intattrs = ["id", "art", "type", "weight", "slot"]
     s = file.read()
     s = file.read()
     index = 0
     index = 0
Line 418: Line 259:
     for i in items:
     for i in items:
         if citems.has_key(i.id):
         if citems.has_key(i.id):
             i.imgurl = imageurls[ citems[i.id]["image"] ]
             i.imagename=citems[i.id]["image"]
            url=i.imagename[0].upper() + i.imagename[1:]
            i.imgurl = "[[Image:"+ url + "]]"
             imagesused[ citems[i.id]["image"]] = 1
             imagesused[ citems[i.id]["image"]] = 1
             i.description = citems[i.id]["description"]
             i.description = citems[i.id]["description"]
Line 436: Line 279:
     typedir = whatever()
     typedir = whatever()
     typedir.healthy = []
     typedir.healthy = []
    typedir.status = []
     typedir.inspiring = []
     typedir.inspiring = []
     typedir.weapons = []
     typedir.weapons = []
Line 453: Line 297:
                 else:
                 else:
                     typedir.inspiring.append(item)
                     typedir.inspiring.append(item)
            elif item.usescript.has_key("sc_start"):
                typedir.status.append(item)
             else: typedir.other.append(item)
             else: typedir.other.append(item)


Line 462: Line 308:
     typedir.inspiring.sort(lambda x,y: int(x.usescript["itemheal"][1]) - int(y.usescript["itemheal"][1]))
     typedir.inspiring.sort(lambda x,y: int(x.usescript["itemheal"][1]) - int(y.usescript["itemheal"][1]))
     #typedir.other.sort(lambda x,y: (x.price+x.sell) - (y.price+y.sell))
     #typedir.other.sort(lambda x,y: (x.price+x.sell) - (y.price+y.sell))
    typedir.status.sort(lambda x,y: (x.price+x.sell) - (y.price+y.sell))


     return typedir
     return typedir
Line 488: Line 335:
     sys.stdout.write('==%s==\n' % title)
     sys.stdout.write('==%s==\n' % title)
     sys.stdout.write('{| border="1" cellspacing="0" cellpadding="5" width="100%" align="center"\n')
     sys.stdout.write('{| border="1" cellspacing="0" cellpadding="5" width="100%" align="center"\n')
     sys.stdout.write('! style="background:#efdead;" | Image\n')
     # Print labels
    sys.stdout.write('! style="background:#efdead;" | Name\n')
     for title in health_titles:
    sys.stdout.write('! style="background:#efdead;" | ID\n')
        sys.stdout.write('! style="background:#efdead;" | %s\n' % title)
    sys.stdout.write('! style="background:#efdead;" | HP Bonus\n')
       
     sys.stdout.write('! style="background:#efdead;" | SP Bonus\n')
    sys.stdout.write('! style="background:#efdead;" | Price<br>BUY/Sell\n')
    sys.stdout.write('! style="background:#efdead;" | Description\n')
     for i in items:
     for i in items:
         sys.stdout.write('|-\n')
         sys.stdout.write('|-\n')
Line 504: Line 348:
         sys.stdout.write('| align="center" | %d\n' % i.usescript["itemheal"][1])
         sys.stdout.write('| align="center" | %d\n' % i.usescript["itemheal"][1])
         sys.stdout.write( getmoneystring(i.price,i.sell) )
         sys.stdout.write( getmoneystring(i.price,i.sell) )
        sys.stdout.write('| align="center!" | %d\n' % i.weight)
        sys.stdout.write('| %s\n' % i.description)
    sys.stdout.write('|}\n\n')
           
def printstatusitems(items,title):
    sys.stdout.write('==%s==\n' % title)
    sys.stdout.write('{| border="1" cellspacing="0" cellpadding="5" width="100%" align="center"\n')
    # Print labels
    for title in status_titles:
        sys.stdout.write('! style="background:#efdead;" | %s\n' % title)
       
    for i in items:
        sys.stdout.write('|-\n')
        sys.stdout.write('| align="center" | %s\n' % i.imgurl)
        #sys.stdout.write('| %s\n' % i.jname.replace('_',' '))
        sys.stdout.write('| %s\n' % i.clientname)
        sys.stdout.write( getidstring(i.id) )
        sys.stdout.write('| align="center" | %s\n' % i.usescript["sc_start"][0])
        sys.stdout.write('| align="center" | %s\n' % i.usescript["sc_start"][1])
        sys.stdout.write('| align="center" | %s\n' % i.usescript["sc_start"][2])
        sys.stdout.write( getmoneystring(i.price,i.sell) )
        sys.stdout.write('| align="center!" | %d\n' % i.weight)
         sys.stdout.write('| %s\n' % i.description)
         sys.stdout.write('| %s\n' % i.description)
     sys.stdout.write('|}\n\n')
     sys.stdout.write('|}\n\n')
Line 511: Line 377:
     sys.stdout.write('==%s==\n' % title)
     sys.stdout.write('==%s==\n' % title)
     sys.stdout.write('{| border="1" cellspacing="0" cellpadding="5" width="100%" align="center"\n')
     sys.stdout.write('{| border="1" cellspacing="0" cellpadding="5" width="100%" align="center"\n')
     sys.stdout.write('! style="background:#efdead;" | Image\n')
     # Print labels
    sys.stdout.write('! style="background:#efdead;" | Name\n')
     for title in weapon_titles:
    sys.stdout.write('! style="background:#efdead;" | ID\n')
        sys.stdout.write('! style="background:#efdead;" | %s\n' % title)
     sys.stdout.write('! style="background:#efdead;" | Damage<br>(Range)\n')
 
    sys.stdout.write('! style="background:#efdead;" | Price<br>BUY/Sell\n')
    sys.stdout.write('! style="background:#efdead;" | Description\n')
     for i in items:
     for i in items:
         sys.stdout.write('|-\n')
         sys.stdout.write('|-\n')
Line 525: Line 389:
         sys.stdout.write('| align="center" | %d (%d)\n' % (i.atk,i.range))
         sys.stdout.write('| align="center" | %d (%d)\n' % (i.atk,i.range))
         sys.stdout.write( getmoneystring(i.price,i.sell) )
         sys.stdout.write( getmoneystring(i.price,i.sell) )
        sys.stdout.write('| align="center!" | %d\n' % i.weight)
         sys.stdout.write('| %s\n' % i.description)
         sys.stdout.write('| %s\n' % i.description)
     sys.stdout.write('|}\n\n')
     sys.stdout.write('|}\n\n')
Line 664: Line 529:
         typedir = gettypedir(items)
         typedir = gettypedir(items)
         if len(typedir.healthy) > 0: printhealitems(typedir.healthy, "Health")
         if len(typedir.healthy) > 0: printhealitems(typedir.healthy, "Health")
        if len(typedir.status) > 0: printstatusitems(typedir.status, "Status")
         if len(typedir.inspiring) > 0: printhealitems(typedir.inspiring, "Mana")
         if len(typedir.inspiring) > 0: printhealitems(typedir.inspiring, "Mana")
         if len(typedir.weapons) > 0: printweaponitems(typedir.weapons, "Weapons")
         if len(typedir.weapons) > 0: printweaponitems(typedir.weapons, "Weapons")
Line 669: Line 535:
         if len(typedir.combos) > 0: printcomboitems(typedir.combos, "Combos")
         if len(typedir.combos) > 0: printcomboitems(typedir.combos, "Combos")
         if len(typedir.other) > 0: printotheritems(typedir.other, "Other")
         if len(typedir.other) > 0: printotheritems(typedir.other, "Other")
        if checkimagesonwiki:
            sys.stdout.write("Checking for images on wiki: \n")
            images = []
            for item in typedir.healthy:
                images.append( (item.imagename, item.description))
            for item in typedir.inspiring:
                images.append( (item.imagename, item.description))
            for item in typedir.weapons:
                images.append( (item.imagename, item.description))
            for item in typedir.armor:
                images.append( (item.imagename, item.description))
            for item in typedir.combos:
                images.append( (item.imagename, item.description))
            for item in typedir.other:
                images.append( (item.imagename, item.description))
            need_to_upload=[]
            for imagename, description in images:
                fixedimagename = imagename[0].upper() + imagename[1:]
                curlstring='curl "http://wiki.themanaworld.org/index.php/' \
                    'Image:%s"' % fixedimagename
                if debug:
                    sys.stdout.write("CHECKING URL: %s\n" % curlstring)
                p=popen2.Popen4(curlstring)
                # this could hang if there is a lot of output!
                returncode = p.wait() # wait for the process to finish
                if debug:
                    sys.stdout.write("Process finished with %d\n" % returncode)
                page = p.fromchild.read()
               
                if debug >= 3:
                    sys.stdout.write("Read: %s\n" % page)
                if page.find("No file by this name exists") != -1:
                    need_to_upload.append((imagename, description))
                    if debug:
                        sys.stdout.write("NEED TO UPLOAD: %s\n" %
                                        str(need_to_upload[-1]))
           
           
            if len(need_to_upload):
                curlstring = 'curl -d "wpName=%s&wpPassword=%s&wpLoginattempt=Log+in" -c cookie-jar "http://wiki.themanaworld.org/index.php?title=Special:Userlogin&action=submitlogin&type=login"'% (wikiuser, wikipassword)
                sys.stdout.write("Logging in as %s, your password can be seen "
                                "in `ps ax`, also this is using http://... "
                                "so be warned!\n" % wikiuser)
                p=popen2.Popen4(curlstring)
                # this could hang if there is a lot of output!
                returncode = p.wait() # wait for the process to finish
                data = p.fromchild.read()
                if debug >= 1:
                    sys.stdout.write("Read: %s\n" % data)
                if data.find("Login error") != -1:
                    sys.stdout.write("Login failed\n")
                if debug:
                    sys.stdout.write("Process finished with %d\n" % returncode)
                sys.stdout.write("Now it is time to upload: %s" %
                                str(need_to_upload))
                for imagename, description in need_to_upload:
                    if debug:
                        sys.stdout.write("Uploading image: %s\n" % imagename)
                    curlstring='curl -b cookie-jar -F "wpUploadFile=@%s/%s" -F "filename=%s" -F "wpDestFile=%s" -F "wpUploadDescription=%s" -F "wpUpload=Upload file" "http://wiki.themanaworld.org/index.php?title=Special:Upload"' % (image_path, imagename, imagename, imagename, description)
                    p=popen2.Popen4(curlstring)
                    # this could hang if there is a lot of output!
                    returncode = p.wait() # wait for the process to finish
                    data = p.fromchild.read()
                    if debug >= 1:
                        sys.stdout.write("Read: %s\n" % data)
                    if debug:
                        sys.stdout.write("Process finished with %d\n" %
                                        returncode)
                    sys.stdout.write("Uploaded: %s, %s\n" % (imagename,
                                                            description))
                   


         printunuseditems("Still unknown")
         printunuseditems("Still unknown")

Revision as of 00:42, 3 September 2007

Archives

Archives of outdated information from this talk page are here:

Problems

itemdbtowiki does not take enough arguments

In the future, itemdbtowiki should be modified to take some extra arguments from the command line, such as 'image_path', 'checkimagesonwiki', and perhaps the username and password.

How to create this page

I have completed the new new script to recreate this page, please leave me a note if you find any problems. It is now capable of uploading new images to the wiki! --Hype0 02:42, 3 September 2007 (CEST)

You can run itemdbtowiki to generate the wiki page. The usage is:

itemdbtowiki <item_db.txt> <items.xml> > wikipage.txt

If run without any arguments, it'll look for item_db.txt and items.xml in the current directory.

To upload new images to the wiki automatically, 'checkimagesonwiki' in the file to 1 and set a corresponding valid 'wikiuser' and 'wikipassword' as well as set the 'image_path' to be correct (these are all parameters at the start of the script.)

Warning: if you choose to upload images, authentication will be done in plaintext, which is exactly what happens if you log in over http:// anyway... just thought you might like a reminder.

Python-Tools

itemdbtowiki

#!/usr/bin/python
#Licensed under GNU General Public License

import sys, os, popen2;
import xml.parsers.expat

debug=0
checkimagesonwiki=0
#wikiuser="Hype0"
#wikipassword="password"
image_path="/usr/home/dex/src/themanaworld/tmw/trunk/data/graphics/items"

health_titles = ["Image","Name","ID","HP Bonus","SP Bonus",
                 "Price<BR />BUY/Sell","Weight","Description"]
status_titles = ["Image","Name","ID","Spell name","Parameter 1","Parameter 2",
                 "Price<BR />BUY/Sell","Weight","Description"]
weapon_titles = [" Image","Name","ID","Damage<BR />(Range)",
                 "Price<BR />BUY/Sell","Weight","Description"]
armor_titles = ["Image", "Name", "ID", "Defense", 
              "Price<BR />BUY/Sell", "Weight","Description"]
other_titles = ["Image","Name","ID","Price<BR />BUY/Sell",
                "Weight","Description "]


imageurls = [
# The index represents the imageID from the items.xml of the client.
    "",  #    0
    "http://img52.imageshack.us/img52/3072/423xc.png",         #   42
    "http://img187.imageshack.us/img187/2963/434dc.png",       #   43
    "http://img125.imageshack.us/img125/4331/442fm.png",       #   44
    "http://img260.imageshack.us/img260/6627/456rj.png",       #   45
    "http://img211.imageshack.us/img211/9089/469fy.png",       #   46
    "http://img219.imageshack.us/img219/1188/479yz.png",       #   47
    "http://img232.imageshack.us/img232/3517/489oa.png",       #   48
    "http://img291.imageshack.us/img291/8643/491eg.png",       #   49
    "http://img157.imageshack.us/img157/1425/502hg.png",       #   50
    "http://img293.imageshack.us/img293/4524/514dn.png",       #   51
    "http://img42.imageshack.us/img42/7271/523hc.png",         #   52
    "http://img187.imageshack.us/img187/5241/535fk.png",       #   53
    "http://img125.imageshack.us/img125/8093/543yr.png",       #   54
    "http://img260.imageshack.us/img260/1315/554bt.png",       #   55
    "http://img211.imageshack.us/img211/9687/564wu.png",       #   56
    "http://img219.imageshack.us/img219/6842/571wz.png",       #   57
    "http://img232.imageshack.us/img232/9236/582ue.png",       #   58
    "http://img291.imageshack.us/img291/435/598ni.png",        #   59
    "http://img157.imageshack.us/img157/1323/605pt.png",       #   60
    "http://img293.imageshack.us/img293/1371/618fu.png",       #   61
    "http://img42.imageshack.us/img42/69/625mj.png",           #   62
    "http://img187.imageshack.us/img187/6240/637ju.png",       #   63
    "http://img275.imageshack.us/img275/9440/648zq.png",       #   64
    "http://img288.imageshack.us/img288/8669/673xe.png",       #   67
    "http://img214.imageshack.us/img214/8675/693wb.png",       #   69
]

imagesused = {}

class whatever: pass

log = []


# parseitems(file)
## Returns list with items from eathena item_db file.

def saveint(string, altval = 0):
    a = 0
    try:
        a = int(string)
    except:
        a = altval
    return a
        
def parsescript(s):
    # Assumes that there's only one call of each method, otherwise it would need to know
    # how to combine those function calls. In practice, the latter call would prevail.
    script = {}
    scriptentry = ""
    parentry = ""
    mode = 0
    for a in s:
        if mode == 0: # looking for method
            if a.isalpha(): 
                mode = 1
                scriptentry += a
            elif a == '}': mode = 9
        elif mode == 1: # reading method name
            if a in " ;}":
                if a == " ": mode = 2
                elif a == ";": mode = 1
                elif a == "}": mode = 9
                parentry = ""
                script[scriptentry] = []
            else: scriptentry += a
        elif mode == 2: #looking for param
            if a == " ": pass
            elif a == ";": 
                mode = 0
                scriptentry = ""
            else:
                mode = 3
                parentry = a
        elif mode == 3: #reading param
            if (a == " ") or (a == ",") or (a == ";"):
                script[scriptentry].append(parentry)
                parentry = ""
                if (a == ';'): 
                    mode = 0
                    scriptentry = ""
                else: mode = 2
            else: 
                parentry += a
        elif mode == 9: #finished
            pass

    # Convert all possible parameters to integers
    for i in script.keys():
        for j in range(len(script[i])):
            try:
                script[i][j] = int(script[i][j])
            except:
                #print script[i][j]
                pass
    return script
    

def parseitems(file):
    objects = []
    for line in file:
        s = line[0:line.find('//')].strip().replace('\t','')
        if s:
            #Replace commas inbetween {} with |, so we can use split
            mode = 0
            sout = ""
            for a in s:
                if mode == 0: #Out of {}
                    if a == '{': mode = 1
                    sout += a
                elif mode == 1: #Inside {}
                    if a == ',': sout += '|'
                    else:
                        sout += a
                        if a == '}': mode = 0

            values = sout.split(',')
            if line[0] == '#':
                if debug:
                    log.append("FOUND COMMENT LINE: %s" % str(values))
                continue
            if (len(values) != 19):
                log.append("item_db: Warning, item-line with ID %s has %d values instead of 19" % (values[0], len(values)))
                if debug:
                    log.append("  line was %s" % str(values))
                while (len(values) < 19):
                    values.append('')
                while (len(values) > 19):
                    values.pop()
            o = whatever()
            o.id        = int(values[0])
            o.name      = values[1]
            o.jname     = values[2]
            o.type      = saveint(values[3])
            o.price     = saveint(values[4])
            o.sell      = saveint(values[5])
            o.weight    = saveint(values[6])
            o.atk       = saveint(values[7])
            o.defense   = saveint(values[8])
            o.range     = saveint(values[9])
            o.slot      = saveint(values[10],-1)
            o.job       = saveint(values[11],-1)
            o.gender    = saveint(values[12],-1)
            o.loc       = saveint(values[13],-1)
            o.wlv       = saveint(values[14])
            o.elv       = saveint(values[15])
            o.view      = saveint(values[16],-1)
            o.usescript = parsescript(values[17].replace('|',','))
            o.equipscript = parsescript(values[18].replace('|',','))


            objects.append(o)

    return objects


# parsexmlitems(file)
## Creates a dictionary containing the values of a client items.xml
## Yeah, there are XML parsers in the standard python libraries, but they're too object
## oriented and thus don't fit the style of this program.
def parsexmlitems(file):
    items = {}
    pre = "<item "
    term = "/>"
    attrs = ["id", "image", "art", "name", "description", "type", "weight", "slot"]
    intattrs = ["id", "art", "type", "weight", "slot"]
    s = file.read()
    index = 0
    debug = 0
    while s[index:].find(pre) >= 0:
        index += s[index:].find(pre) + len(pre)
        curitem = {}
        termstart = index + s[index:].find(term) + len(term)

        for attr in attrs:
            found = s[index:].find(attr+'="')
            if found >= 0:
                start = index + found + len(attr+'="')
                end= start + s[start:].find('"')
            else:
                start = termstart

            if (start < termstart):
                curitem[attr] = s[start:end]

        for a in intattrs:
            try:
                if curitem.has_key(a): curitem[a] = int(curitem[a])
            except:
                log.append("Item-ID %s: Cannot convert integer attribute %s to an integer. Value: '%s'" % (curitem["id"], a, curitem[a]))

        items[curitem['id']] = curitem


    return items
        

# addclientinformation(items, citems)
## Entends the item data with the data collected from the client items.xml. Adding imageurls,
## client-name and -description

def addclientinformation(items,citems):
    global imageurls
    global imagesused
    for i in items:
        if citems.has_key(i.id):
            i.imagename=citems[i.id]["image"]
            url=i.imagename[0].upper() + i.imagename[1:]
            i.imgurl = "[[Image:"+ url + "]]"
            imagesused[ citems[i.id]["image"]] = 1
            i.description = citems[i.id]["description"]
            i.clientname = citems[i.id]["name"]
        else:
            i.imgurl = ''
            i.description = ''
            i.clientname = ''



# gettypedir (items)
## Returns sorted lists of items by itemtype
def gettypedir(items):
    items.sort(lambda x,y: (x.price+x.sell) - (y.price+y.sell))

    typedir = whatever()
    typedir.healthy = []
    typedir.status = []
    typedir.inspiring = []
    typedir.weapons = []
    typedir.combos = []
    typedir.armor = []
    typedir.other = []
    for item in items:
        if (item.imgurl.strip() or item.clientname.strip()):
            #if item.id == 537: log.append('"%s", "%s"' % (item.imgurl, item.name)
            if (item.atk > 0):
                if item.defense == 0: typedir.weapons.append(item)
                else: typedir.combos.append(item)
            elif (item.defense > 0): typedir.armor.append(item)
            elif item.usescript.has_key("itemheal"): 
                if item.usescript["itemheal"][0] > item.usescript["itemheal"][1]: 
                    typedir.healthy.append(item)
                else:
                    typedir.inspiring.append(item)
            elif item.usescript.has_key("sc_start"):
                typedir.status.append(item)
            else: typedir.other.append(item)

    typedir.weapons.sort(lambda x,y: x.atk - y.atk)
    typedir.armor.sort(lambda x,y: x.defense - y.defense)
    typedir.combos.sort(lambda x,y: (x.defense+x.atk) - (y.defense+y.atk))

    typedir.healthy.sort(lambda x,y: int(x.usescript["itemheal"][0]) - int(y.usescript["itemheal"][0]))
    typedir.inspiring.sort(lambda x,y: int(x.usescript["itemheal"][1]) - int(y.usescript["itemheal"][1]))
    #typedir.other.sort(lambda x,y: (x.price+x.sell) - (y.price+y.sell))
    typedir.status.sort(lambda x,y: (x.price+x.sell) - (y.price+y.sell))

    return typedir
    

            
# printlog()
## Prints the global variable log to stdout
def printlog():
    global log
    if len(log) > 0:
        sys.stdout.write('\n---------------------------------------\n')
    for line in log:
        sys.stdout.write(line+'\n')


# print<>items(items, title)
## Creates the table in wikicode, depending on what kind of item is being printed

def getmoneystring(buy, sell):
    return '| align="right" | %d GP<br>%d gp\n' % (buy,sell)
def getidstring(id):
    return '| align="center" | [%d]\n' % id
    
def printhealitems(items,title):
    sys.stdout.write('==%s==\n' % title)
    sys.stdout.write('{| border="1" cellspacing="0" cellpadding="5" width="100%" align="center"\n')
    # Print labels
    for title in health_titles:
        sys.stdout.write('! style="background:#efdead;" | %s\n' % title)
        
    for i in items:
        sys.stdout.write('|-\n')
        sys.stdout.write('| align="center" | %s\n' % i.imgurl)
        #sys.stdout.write('| %s\n' % i.jname.replace('_',' '))
        sys.stdout.write('| %s\n' % i.clientname)
        sys.stdout.write( getidstring(i.id) )
        sys.stdout.write('| align="center" | %d\n' % i.usescript["itemheal"][0])
        sys.stdout.write('| align="center" | %d\n' % i.usescript["itemheal"][1])
        sys.stdout.write( getmoneystring(i.price,i.sell) )
        sys.stdout.write('| align="center!" | %d\n' % i.weight)
        sys.stdout.write('| %s\n' % i.description)
    sys.stdout.write('|}\n\n')
            
def printstatusitems(items,title):
    sys.stdout.write('==%s==\n' % title)
    sys.stdout.write('{| border="1" cellspacing="0" cellpadding="5" width="100%" align="center"\n')
    # Print labels
    for title in status_titles:
        sys.stdout.write('! style="background:#efdead;" | %s\n' % title)
        
    for i in items:
        sys.stdout.write('|-\n')
        sys.stdout.write('| align="center" | %s\n' % i.imgurl)
        #sys.stdout.write('| %s\n' % i.jname.replace('_',' '))
        sys.stdout.write('| %s\n' % i.clientname)
        sys.stdout.write( getidstring(i.id) )
        sys.stdout.write('| align="center" | %s\n' % i.usescript["sc_start"][0])
        sys.stdout.write('| align="center" | %s\n' % i.usescript["sc_start"][1])
        sys.stdout.write('| align="center" | %s\n' % i.usescript["sc_start"][2])
        sys.stdout.write( getmoneystring(i.price,i.sell) )
        sys.stdout.write('| align="center!" | %d\n' % i.weight)
        sys.stdout.write('| %s\n' % i.description)
    sys.stdout.write('|}\n\n')
            

def printweaponitems(items, title):
    sys.stdout.write('==%s==\n' % title)
    sys.stdout.write('{| border="1" cellspacing="0" cellpadding="5" width="100%" align="center"\n')
    # Print labels
    for title in weapon_titles:
        sys.stdout.write('! style="background:#efdead;" | %s\n' % title)

    for i in items:
        sys.stdout.write('|-\n')
        sys.stdout.write('| align="center" | %s\n' % i.imgurl)
        #sys.stdout.write('| %s\n' % i.jname.replace('_',' '))
        sys.stdout.write('| %s\n' % i.clientname)
        sys.stdout.write( getidstring(i.id) )
        sys.stdout.write('| align="center" | %d (%d)\n' % (i.atk,i.range))
        sys.stdout.write( getmoneystring(i.price,i.sell) )
        sys.stdout.write('| align="center!" | %d\n' % i.weight)
        sys.stdout.write('| %s\n' % i.description)
    sys.stdout.write('|}\n\n')
    
def printarmoritems(items, title):
    sys.stdout.write('==%s==\n' % title)
    sys.stdout.write('{| border="1" cellspacing="0" cellpadding="5" width="100%" align="center"\n')
    sys.stdout.write('! style="background:#efdead;" | Image\n')
    sys.stdout.write('! style="background:#efdead;" | Name\n')
    sys.stdout.write('! style="background:#efdead;" | ID\n')
    sys.stdout.write('! style="background:#efdead;" | Defense\n')
    sys.stdout.write('! style="background:#efdead;" | Price<br>BUY/Sell\n')
    sys.stdout.write('! style="background:#efdead;" | Description\n')
    for i in items:
        sys.stdout.write('|-\n')
        sys.stdout.write('| align="center" | %s\n' % i.imgurl)
        #sys.stdout.write('| %s\n' % i.jname.replace('_',' '))
        sys.stdout.write('| %s\n' % i.clientname)
        sys.stdout.write( getidstring(i.id) )
        sys.stdout.write('| align="center" | %d\n' % i.defense)
        sys.stdout.write( getmoneystring(i.price,i.sell) )
        sys.stdout.write('| %s\n' % i.description)
    sys.stdout.write('|}\n\n')

def printcomboitems(items, title):
    sys.stdout.write('==%s==\n' % title)
    sys.stdout.write('{| border="1" cellspacing="0" cellpadding="5" width="100%" align="center"\n')
    sys.stdout.write('! style="background:#efdead;" | Image\n')
    sys.stdout.write('! style="background:#efdead;" | Name\n')
    sys.stdout.write('! style="background:#efdead;" | ID\n')
    sys.stdout.write('! style="background:#efdead;" | Damage<br>(Range)\n')
    sys.stdout.write('! style="background:#efdead;" | Defense\n')
    sys.stdout.write('! style="background:#efdead;" | Price<br>BUY/Sell\n')
    sys.stdout.write('! style="background:#efdead;" | Description\n')
    for i in items:
        sys.stdout.write('|-\n')
        sys.stdout.write('| align="center" | %s\n' % i.imgurl)
        #sys.stdout.write('| %s\n' % i.jname.replace('_',' '))
        sys.stdout.write('| %s\n' % i.clientname)
        sys.stdout.write( getidstring(i.id) )
        sys.stdout.write('| align="center" | %d (%d)\n' % (i.atk,i.range))
        sys.stdout.write('| align="center" | %d\n' % i.defense)
        sys.stdout.write( getmoneystring(i.price,i.sell) )
        sys.stdout.write('| %s\n' % i.description)
    sys.stdout.write('|}\n\n')

def getpropertystring(item):
    s = ""
    s += "Weight: %d, " % item.weight
    s += "Slot: %d, " % item.slot
    s += "Job: %d, " % item.job
    s += "Gender: %d, " % item.gender
    s += "Loc: %d, " % item.loc
    s += "wLV: %d, " % item.wlv
    s += "eLV: %d, " % item.wlv
    s += "View: %d " % item.view
    return s


def printotheritems(items, title):
    sys.stdout.write('==%s==\n' % title)
    sys.stdout.write('{| border="1" cellspacing="0" cellpadding="5" width="100%" align="center"\n')
    sys.stdout.write('! style="background:#efdead;" | Image\n')
    sys.stdout.write('! style="background:#efdead;" | Name\n')
    sys.stdout.write('! style="background:#efdead;" | ID\n')
    #sys.stdout.write('! style="background:#efdead;" | Type\n')
    #sys.stdout.write('! style="background:#efdead;" | Properties\n')
    sys.stdout.write('! style="background:#efdead;" | Price<br>BUY/Sell\n')
    sys.stdout.write('! style="background:#efdead;" | Description\n')
    for i in items:
        sys.stdout.write('|-\n')
        sys.stdout.write('| align="center" | %s\n' % i.imgurl)
        #sys.stdout.write('| %s\n' % i.jname.replace('_',' '))
        sys.stdout.write('| %s\n' % i.clientname)
        sys.stdout.write( getidstring(i.id) )
        #sys.stdout.write('| align="center" | %d\n' % i.type)
        #sys.stdout.write('| align="center" | %s\n' % getpropertystring(i))
        sys.stdout.write( getmoneystring(i.price,i.sell) )
        sys.stdout.write('| %s\n' % i.description)
    sys.stdout.write('|}\n\n')



def printunuseditems(title):
    global imageurls
    global imagesused
    ids = []
    for i in range(1,len(imageurls)):
        if not imagesused.has_key(i):
            ids.append(i)
    if len(ids):
        sys.stdout.write('==%s==\n' % title)
        sys.stdout.write('{| border="1" cellspacing="0" cellpadding="5" width="100%" align="center"\n')
        sys.stdout.write('| ')
        for i in ids:
            sys.stdout.write(imageurls[i] + ' ')
        sys.stdout.write('\n|}\n\n')

    

#####################################################################
#  MAIN
#####################################################################

try:
    if (len(sys.argv) == 1):
        item_db = "item_db.txt"
        item_xml = "items.xml"
    elif (len(sys.argv) == 3):
        item_db = sys.argv[1]
        item_xml = sys.argv[2]
    else: 
        item_db = ''
        item_xml = ''
        sys.stdout.write("Wrong number of arguments\n")

    if item_db and (not os.path.isfile(item_db)):
        sys.stdout.write("File does not exist: %s\n" % item_db)
        item_db = ''
    if item_xml and (not os.path.isfile(item_xml)):
        sys.stdout.write("File does not exist: %s\n" % item_db)
        item_db = ''
    
    if not (item_db and item_xml):
        sys.stdout.write("\nUSAGE:\n")
        sys.stdout.write("dbtowiki without any arguments will use item_db.txt and items.xml in the current directory.\n")
        sys.stdout.write("to specify custom files, call: dbtowiki <item_db> <item_xml>\n")
        exit(-1);
    else:
        log.append("Item-list [item_db] = %s" % item_db)
        log.append("Item-list [item_xml] = %s" % item_xml)
        f = open(item_db)
        items = parseitems(f);
        f = open(item_xml)
        citems = parsexmlitems(f);

        addclientinformation(items, citems)

        typedir = gettypedir(items)
        if len(typedir.healthy) > 0: printhealitems(typedir.healthy, "Health")
        if len(typedir.status) > 0: printstatusitems(typedir.status, "Status")
        if len(typedir.inspiring) > 0: printhealitems(typedir.inspiring, "Mana")
        if len(typedir.weapons) > 0: printweaponitems(typedir.weapons, "Weapons")
        if len(typedir.armor) > 0: printarmoritems(typedir.armor, "Armor")
        if len(typedir.combos) > 0: printcomboitems(typedir.combos, "Combos")
        if len(typedir.other) > 0: printotheritems(typedir.other, "Other")

        if checkimagesonwiki:
            sys.stdout.write("Checking for images on wiki: \n")
            images = []
            for item in typedir.healthy:
                images.append( (item.imagename, item.description))
            for item in typedir.inspiring:
                images.append( (item.imagename, item.description))
            for item in typedir.weapons:
                images.append( (item.imagename, item.description))
            for item in typedir.armor:
                images.append( (item.imagename, item.description)) 
            for item in typedir.combos:
                images.append( (item.imagename, item.description))
            for item in typedir.other:
                images.append( (item.imagename, item.description))

            need_to_upload=[]

            for imagename, description in images:
                fixedimagename = imagename[0].upper() + imagename[1:]
                curlstring='curl "http://wiki.themanaworld.org/index.php/' \
                    'Image:%s"' % fixedimagename
                if debug:
                    sys.stdout.write("CHECKING URL: %s\n" % curlstring)
                p=popen2.Popen4(curlstring) 
                # this could hang if there is a lot of output!
                returncode = p.wait() # wait for the process to finish
                if debug:
                    sys.stdout.write("Process finished with %d\n" % returncode)
                page = p.fromchild.read()
                
                if debug >= 3:
                    sys.stdout.write("Read: %s\n" % page)

                if page.find("No file by this name exists") != -1:
                    need_to_upload.append((imagename, description))
                    if debug:
                        sys.stdout.write("NEED TO UPLOAD: %s\n" % 
                                         str(need_to_upload[-1]))
            
            

            if len(need_to_upload):
                curlstring = 'curl -d "wpName=%s&wpPassword=%s&wpLoginattempt=Log+in" -c cookie-jar "http://wiki.themanaworld.org/index.php?title=Special:Userlogin&action=submitlogin&type=login"'% (wikiuser, wikipassword)

                sys.stdout.write("Logging in as %s, your password can be seen "
                                 "in `ps ax`, also this is using http://... "
                                 "so be warned!\n" % wikiuser)
                p=popen2.Popen4(curlstring) 
                # this could hang if there is a lot of output!
                returncode = p.wait() # wait for the process to finish
                data = p.fromchild.read()
                if debug >= 1:
                    sys.stdout.write("Read: %s\n" % data)

                if data.find("Login error") != -1:
                    sys.stdout.write("Login failed\n")

                if debug:
                    sys.stdout.write("Process finished with %d\n" % returncode)

                sys.stdout.write("Now it is time to upload: %s" % 
                                 str(need_to_upload))

                for imagename, description in need_to_upload:
                    if debug:
                        sys.stdout.write("Uploading image: %s\n" % imagename)

                    curlstring='curl -b cookie-jar -F "wpUploadFile=@%s/%s" -F "filename=%s" -F "wpDestFile=%s" -F "wpUploadDescription=%s" -F "wpUpload=Upload file" "http://wiki.themanaworld.org/index.php?title=Special:Upload"' % (image_path, imagename, imagename, imagename, description)
                    p=popen2.Popen4(curlstring) 
                    # this could hang if there is a lot of output!
                    returncode = p.wait() # wait for the process to finish
                    data = p.fromchild.read()
                    if debug >= 1:
                        sys.stdout.write("Read: %s\n" % data)

                    if debug:
                        sys.stdout.write("Process finished with %d\n" % 
                                         returncode)

                    sys.stdout.write("Uploaded: %s, %s\n" % (imagename,
                                                             description))
                    

        printunuseditems("Still unknown")

        sys.stdout.write("\n\n")

finally:
    printlog()