These forums have been archived and are now read-only.

The new forums are live and can be found at https://forums.eveonline.com/

EVE Technology Lab

 
  • Topic is locked indefinitely.
 

Reverence - 100% compatible EVE cache library for Python

First post
Author
Taleden
North Wind Local no. 612
#121 - 2013-08-19 16:08:32 UTC
Kaladr wrote:
malaire wrote:
6ie wrote:
Slightly related - Anyone know why after some time (hours) of scanning the market, the eve client stops creating cache files in CachedMethodCalls? (Rather it creates 1 out of every 7 or so scans).

There seems to be at least 2 limitations for showMarketDetails javascript call.

1) max 1 call per second
2) max N calls in X seconds (or something like that)

If I use quick loop with 40 calls and 2.5 second wait between calls, it works. But if I leave that running repeatedly then after some time showMarketDetails just stops working without any warning about too many calls (i.e. it just doesn't open market details anymore).

Currently my script is using 10 second wait between calls, and 20 second wait between batches of 40 calls or so. This has never stopped working so far even after hours, but might be an overkill. But since this is enough for me I havn't tried finding optimal wait time.


Another technique to refresh the IGB page (window.location = blah works).


Is this still a thing? I've run scans for hours at a time with a 4s delay between queries, and as far as I can tell it kept right on -- at least, the market window kept updating to new items, although I didn't manually check if new cache files were still being created.
Kadesh Priestess
Descendance.
GoonSwarm.
#122 - 2013-08-20 18:49:43 UTC
Taleden wrote:
So the subgroup records are there, and i.e. config.typesByMarketGroups[1671] returns the right items, but the subgroup names are missing. They do have marketGroupNameID values however, so I wonder where the text is supposed to be pulled from?
Localization pickles. Reverence contains some infrastructure to replace various text fields with their localized counterparts, but i never used it myself so have no idea if it's good enough.
Lomba Kallu
State War Academy
Caldari State
#123 - 2013-08-21 03:03:27 UTC
I tried running reverence on Sisi, and got this error:
"UnmarshalError: find_global failed to resolve: carbon.common.script.sys.crowset.CRowset"

A call to "cfg.invtypematerials.iteritems()" generates that error.

"cfg" is defined as: cfg = eve.getconfigmgr()

"eve" is defined as: eve = blue.EVE(eve_root, server)

where eve_root = r"C:\Program Files (x86)\CCP\EVE_Buck", ad server = "Singularity"



The same code works just fine on Tranquility.

Perhaps the cache format has changed in Sisi?

Also, a Windows 64-bit installer that incorporates the changes from 3 months ago would be great. Otherwise Visual Studio 2008 related errors crop up.
Entity
X-Factor Industries
Synthetic Existence
#124 - 2013-08-21 16:07:11 UTC
Lomba Kallu wrote:
Perhaps the cache format has changed in Sisi?.


CCP completely overhauled the namespace shenanigans, as well as altered the FSD stuff again. Updating reverence to work with the new hierarchy/architecture requires a considerable amount of work.
I am not in the same country as my dev machine for the time being, though, so it's a bit tricky for me to work on reverence atm :P

One can probably restore basic functionality by editing the _find_global function in blue.py (you can point it to the right objects it asks for from there)

╦......║...╔╗.║.║.╔╗.╦║.╔╗╔╦╗╔╗

║.╔╗╔╗╔╣.╔╗╠..╠ ╠╗╠╝.║╠ ╠╝║║║╚╗

╩═╚╝║.╚╝.╚╝║..╚╝║║╚╝.╩╚╝╚╝║.║╚╝

Got Item?

Aineko Macx
#125 - 2013-09-04 18:12:19 UTC
Thx for the hard work Entity.
The current hickup (which won't be the last, thanks to the evolving nature of eve) is a reason to once more call for an official market data feed from CCP: https://forums.eveonline.com/default.aspx?g=posts&t=274786
Drapko Nitzhonot
Abdera Logistics
#126 - 2013-09-06 02:03:03 UTC  |  Edited by: Drapko Nitzhonot
Officially fixed
Entity
X-Factor Industries
Synthetic Existence
#127 - 2013-09-23 15:22:24 UTC  |  Edited by: Entity
Sorry for the late update but aside from not being in the country and figuring out the FSD stuff, I had enough to do :P

Anyway, without further ado:

Reverence 1.6.0 (aka the Odyssey 1.1 update) has been pushed to github

Source distribution, 32bits and 64bits binaries are available here:
Downloads

Notable changes:

- The only officially supported python version is now Python 2.7.
- This update is NOT BACKWARDS COMPATIBLE with older EVE client versions.
- Massively improved FSD support: Higher performance, less RAM usage.
- the cfg.fsdTypeOverrides table is now correctly used by cfg.invtypes.


The examples on github are still out of date. Sorry about that.

EDIT: it appears a syntax error snuck by! it's fixed. if you downloaded 1.6.0 before this edit, download it again :)

╦......║...╔╗.║.║.╔╗.╦║.╔╗╔╦╗╔╗

║.╔╗╔╗╔╣.╔╗╠..╠ ╠╗╠╝.║╠ ╠╝║║║╚╗

╩═╚╝║.╚╝.╚╝║..╚╝║║╚╝.╩╚╝╚╝║.║╚╝

Got Item?

Vaerah Vahrokha
Vahrokh Consulting
#128 - 2013-09-28 06:46:49 UTC
Entity wrote:
Sorry for the late update but aside from not being in the country and figuring out the FSD stuff, I had enough to do :P

Anyway, without further ado:

Reverence 1.6.0 (aka the Odyssey 1.1 update) has been pushed to github

Source distribution, 32bits and 64bits binaries are available here:
Downloads

Notable changes:

- The only officially supported python version is now Python 2.7.
- This update is NOT BACKWARDS COMPATIBLE with older EVE client versions.
- Massively improved FSD support: Higher performance, less RAM usage.
- the cfg.fsdTypeOverrides table is now correctly used by cfg.invtypes.


The examples on github are still out of date. Sorry about that.

EDIT: it appears a syntax error snuck by! it's fixed. if you downloaded 1.6.0 before this edit, download it again :)


Thank you!
Vaerah Vahrokha
Vahrokh Consulting
#129 - 2013-09-29 15:27:02 UTC  |  Edited by: Vaerah Vahrokha
I found an issue using the new version, the same scripts that used to work before the update now do nothing.

OS is Windows 7 Professional, python = 2.7.3.

This is the offending source code (the same that used to work):

EVEROOT = r"D:/Program Files/CCP/EVE"
OUTPATH = r"D:/Temp/EvEDumps/"
...
import time
import os
from reverence import blue
from time import sleep
...
eve = blue.EVE(EVEROOT)
cfg = eve.getconfigmgr()
cachemgr = eve.getcachemgr()
cmc = cachemgr.LoadCacheFolder("CachedMethodCalls")

I think this code comes from some of the provided examples and worked for years.

What stopped working is that now cmc = {} while it used to load whole collections.

Now I am not a Python guy so I just write down what I have seen debugging the calls:

I went to the object initialization

File: Cache.py

class CacheMgr:
def __init__(self, root, servername="Tranquility...

it finds the correct cache path and then cycles several Machonet folders till it gets to

u'C:\\\\Users\\\\user_name...\\\cache\\\\bulkdata\\\\379

Protocol found says 379 as well

then

appdatapath = u'C:\\\\Users\\\\user_name...m_files_ccp_eve_tranquility'

then it assigns some members in this bit of code:

if protocol > self.machoVersion:
self.machoVersion = protocol
self.root = root
self.appdatapath = appdatapath
self.cachepath = _join(appdatapath, "cache")
self.settingspath = _join(appdatapath, "settings")
self.machocachepath = _join(machopath, str(protocol))
self.BULK_SYSTEM_PATH = _join(root, 'bulkdata')
self.BULK_CACHE_PATH = _join(appdatapath, 'cache', 'bulkdata', str(protocol))
return

I can't see the self data members value, I don't know if it can be done with IDLE.

Later on the program gets to my

cmc = cachemgr.LoadCacheFolder("CachedMethodCalls")

call and enters this function:

def LoadCacheFolder(self, name, filter="*.cache"):
"""Loads all .cache files from specified folder. Returns a dict keyed on object name."""

# Note that this method is used mainly for debugging and testing,
# and is subject to change without notice.
crap = {}
for filename in glob.glob(_join(name, filter)):
what, obj = blue.marshal.Load(_readfile(filename))
crap[what] = obj
return crap

In there it starts the for cycle with name = "CachedMethodCalls" but it never gets to the inner loop and immediately returns crap, which of course is set to {} and thus my cmc collection is {} as well.


I have this folder with these contents:

C:\Users\user_name\AppData\Local\CCP\EVE\d_program_files_ccp_eve_tranquility\cache\MachoNet\87.237.38.200\379

CachedMethodCalls
CachedObjects
MethodCallCachingDetails


CachedMethodCalls in turn has a lot of *.cache files, like:

1ddd.cache
1ebb.cache
2b41.cache

These files were modified today (I refreshed the whole client cache).


Any idea about what I could do to fix this?
Entity
X-Factor Industries
Synthetic Existence
#130 - 2013-09-29 15:30:47 UTC
Vaerah Vahrokha wrote:
Any idea about what I could do to fix this?


LoadCacheFolder() takes an explicit path. not just a macho folder name.

Edit: and as stated above, the examples are woefully out of date :P

╦......║...╔╗.║.║.╔╗.╦║.╔╗╔╦╗╔╗

║.╔╗╔╗╔╣.╔╗╠..╠ ╠╗╠╝.║╠ ╠╝║║║╚╗

╩═╚╝║.╚╝.╚╝║..╚╝║║╚╝.╩╚╝╚╝║.║╚╝

Got Item?

Vaerah Vahrokha
Vahrokh Consulting
#131 - 2013-09-29 15:49:45 UTC  |  Edited by: Vaerah Vahrokha
Entity wrote:
Vaerah Vahrokha wrote:
Any idea about what I could do to fix this?


LoadCacheFolder() takes an explicit path. not just a macho folder name.

Edit: and as stated above, the examples are woefully out of date :P



Yeah just found out that the glob mechanism called by the offending function:

def glob1(dirname, pattern):
if not dirname:
dirname = os.curdir
if isinstance(pattern, unicode) and not isinstance(dirname, unicode):
dirname = unicode(dirname, sys.getfilesystemencoding() or
sys.getdefaultencoding())
try:
names = os.listdir(dirname)
except os.error

it fails os.listdir(dirname) with error 3: "Directory not found".


I wonder how it worked for so long without ever specifying the absolute path O_o. Even stranger, there are dozens of people who used this script and no one had it break due to the relative path. Shocked


Since I am totally ignorant about Python, what should I write to get the correct Machonet absolute path? I suppose I have to put a method call or data member from the cfg manager or the eve object?
Entity
X-Factor Industries
Synthetic Existence
#132 - 2013-09-29 16:11:13 UTC
Vaerah Vahrokha wrote:


Since I am totally ignorant about Python, what should I write to get the correct Machonet absolute path? I suppose I have to put a method call or data member from the cfg manager or the eve object?



os.path.join(c.machocachepath, "CachedMethodCalls")

╦......║...╔╗.║.║.╔╗.╦║.╔╗╔╦╗╔╗

║.╔╗╔╗╔╣.╔╗╠..╠ ╠╗╠╝.║╠ ╠╝║║║╚╗

╩═╚╝║.╚╝.╚╝║..╚╝║║╚╝.╩╚╝╚╝║.║╚╝

Got Item?

Vaerah Vahrokha
Vahrokh Consulting
#133 - 2013-09-29 16:38:12 UTC
Thank you now it works ^^
Vaerah Vahrokha
Vahrokh Consulting
#134 - 2013-09-30 01:02:10 UTC
I have found where I copied the "relative path" code that worked in the past but not today. It's your own example. P

Entity wrote:

Well yeah modifying the example to use CMC isn't going to work because CachedMethodCalls are different objects.

try something like this:

from reverence import blue

eve = blue.EVE("C:/path/to/eve")
cm = eve.getcachemgr()
crap = cm.LoadCacheFolder("CachedMethodCalls")

for key, obj in crap.iteritems():
if "GetOrders" in key:
orders = obj['lret']
for order in orders[0]: # 0 for sell, 1 for buy orders
print order.orderID, order.price, int(order.volRemaining)


Man, time's passing fast. That's 2010 stuff.
Vaerah Vahrokha
Vahrokh Consulting
#135 - 2013-09-30 02:21:40 UTC
Another colorful error. The script now works fine.

I need to bundle the script plus assorted Python runtime in an executable.

I setup pyinstaller and it creates a "dist" folder with the generated executable inside.

But when I start it I get:

File "string", line 111, in module
File "E:\Python27\Scripts\build\Blah\out00-PYZ.pyz\reverence.cache", line 259, in LoadCacheFolder
UnmarshalError: find_global failed to resolve: carbon.common.script.net.objectCaching.CachedMethodCallResult

What's that?

In PHP I could fix all by myself but Python seems to love cryptic messages I don't understand.

In the folder there are reverence._blue.pyd and reverence._pyFSD.pyd.
Entity
X-Factor Industries
Synthetic Existence
#136 - 2013-09-30 11:23:07 UTC
Vaerah Vahrokha wrote:
I need to bundle the script plus assorted Python runtime in an executable.


If it's anything like py2exe you need to make sure all the required files are included in the binary by the thingy that makes the binary. Reverence uses a lot of dynamic imports (particularly for decoding stuff) so any exe creation tool that tries to figure out what to include needs to be given hints as it can't determine it from the static import statements in the code alone.

╦......║...╔╗.║.║.╔╗.╦║.╔╗╔╦╗╔╗

║.╔╗╔╗╔╣.╔╗╠..╠ ╠╗╠╝.║╠ ╠╝║║║╚╗

╩═╚╝║.╚╝.╚╝║..╚╝║║╚╝.╩╚╝╚╝║.║╚╝

Got Item?

Vaerah Vahrokha
Vahrokh Consulting
#137 - 2013-09-30 12:17:42 UTC
Entity wrote:
Vaerah Vahrokha wrote:
I need to bundle the script plus assorted Python runtime in an executable.


If it's anything like py2exe you need to make sure all the required files are included in the binary by the thingy that makes the binary. Reverence uses a lot of dynamic imports (particularly for decoding stuff) so any exe creation tool that tries to figure out what to include needs to be given hints as it can't determine it from the static import statements in the code alone.



I have no problem compiling stuff (I have Visual Studio and compiled Reverence "the hard way"), but I don't know how to learn which file is missing.

I mean, this Carbon.common.script.net.objectCaching.CachedMethodCallResult has to be implemented somewhere, doesn't it?

If I understand correctly, I have to find a .PYD file. Compiling Reverence with Visual Studio creates two of those files: reverence._blue.pyd and reverence._pyFSD.pyd.

So, which PYD file implements Carbon.common.script.blah.blah? Is there a python tool that shows the dependencies?
Entity
X-Factor Industries
Synthetic Existence
#138 - 2013-09-30 13:49:09 UTC
Vaerah Vahrokha wrote:
Entity wrote:
Vaerah Vahrokha wrote:
I need to bundle the script plus assorted Python runtime in an executable.


If it's anything like py2exe you need to make sure all the required files are included in the binary by the thingy that makes the binary. Reverence uses a lot of dynamic imports (particularly for decoding stuff) so any exe creation tool that tries to figure out what to include needs to be given hints as it can't determine it from the static import statements in the code alone.



I have no problem compiling stuff (I have Visual Studio and compiled Reverence "the hard way"), but I don't know how to learn which file is missing.

I mean, this Carbon.common.script.net.objectCaching.CachedMethodCallResult has to be implemented somewhere, doesn't it?

If I understand correctly, I have to find a .PYD file. Compiling Reverence with Visual Studio creates two of those files: reverence._blue.pyd and reverence._pyFSD.pyd.

So, which PYD file implements Carbon.common.script.blah.blah? Is there a python tool that shows the dependencies?


No, they are python files. That entire carbon.blabla hierarchy is just python files (look at the github source tree). As I said, I think your packaging tool simply doesn't know it has to include those files. See the similar issue here.

╦......║...╔╗.║.║.╔╗.╦║.╔╗╔╦╗╔╗

║.╔╗╔╗╔╣.╔╗╠..╠ ╠╗╠╝.║╠ ╠╝║║║╚╗

╩═╚╝║.╚╝.╚╝║..╚╝║║╚╝.╩╚╝╚╝║.║╚╝

Got Item?

Vaerah Vahrokha
Vahrokh Consulting
#139 - 2013-09-30 17:13:25 UTC
Entity wrote:

No, they are python files. That entire carbon.blabla hierarchy is just python files (look at the github source tree). As I said, I think your packaging tool simply doesn't know it has to include those files


Thank you for your continued support!

The solution you have shown is exactly what used to work for years. I found it out the hard way (I did not read that options post of yours) so I had this setup.py:

from distutils.core import setup
import py2exe

setup(
console=['EvEMarketHistory.py'],
options={
'py2exe':
{
'packages': ['reverence'],
'includes': ['reverence', 'os'],
}
}
)

This setup worked perfectly, till the last Reverence release.
Now by using the same build py2exe batch it runs for a while and at the end it fails with:

The following modules appear to be missing
['Carbon', 'Carbon.Files', 'blue', 'fsdSchemas.binaryLoader']


So I switched to another executable compiler. It compiles my script perfectly but when I start the compiled script:

Traceback (most recent call last):
File "string", line 111, in module
File "E:\Python27\Scripts\build\EvEMarketHistory\out00-PYZ.pyz\reverence.cache", line 259, in LoadCacheFolder
UnmarshalError: find_global failed to resolve: carbon.common.script.net.objectCaching.CachedMethodCallResult
Exception TypeError: 'expected string or Unicode object, NoneType found' in module 'threading' from 'E:\Python27\Scripts\dist\EVEMAR~1\threading.pyc' ignored


So even with the option to include reverence and even trying 2 different compilers it still has something ugly going on with Carbon.
Entity
X-Factor Industries
Synthetic Existence
#140 - 2013-09-30 19:22:16 UTC
Vaerah Vahrokha wrote:
So even with the option to include reverence and even trying 2 different compilers it still has something ugly going on with Carbon.


Yes well the only way to get that error is if your final exe does not include those files.

you could try modifying reverence to explicitly import the entire carbon.* and eve.* hierarchies in the __init__.py, that will probably make your packaging thingy clue in.

(ie. import reverence.carbon.common.script.net.objectCaching etc.)

╦......║...╔╗.║.║.╔╗.╦║.╔╗╔╦╗╔╗

║.╔╗╔╗╔╣.╔╗╠..╠ ╠╗╠╝.║╠ ╠╝║║║╚╗

╩═╚╝║.╚╝.╚╝║..╚╝║║╚╝.╩╚╝╚╝║.║╚╝

Got Item?