aurelienpierre / clean-nextloud-s3

0 stars 0 forks source link

TypeError: 'int' object is not subscriptable #1

Open d3v3l15h opened 1 month ago

d3v3l15h commented 1 month ago

Hello,

First thanks for the script !

I made some modifications to connect to Minio S3 server and connection/data retrieval seems to be OK as I get :

Detected 3129   files from S3 bucket
Detected 4847   entries (files + folders) from oc_filecache
Detected 3125   files from oc_filecache

Detected 388    empty folders from oc_files
Detected 0      empty folders from oc_files that have an S3 ID match

Detected 4      orphaned file previews from oc_filecache [no original file]
Detected 4      orphaned IDs from S3 [no match in oc_filecache]
Detected 0      orphaned file IDs from DB [no match in S3]
------------------------------------------------------------------
Do you wish to cleanup ? Type `y` to proceed:

but then, if I proceed, I get :


Traceback (most recent call last):
  File "/root/clean-nextloud-s3/main.py", line 122, in <module>
    fileid = orphan[0]
TypeError: 'int' object is not subscriptable

Thanks in advance for your help as I'm no python expert.

EM

aurelienpierre commented 1 month ago

Hi,

I'm guessing this comes from the loop:

  for orphan in previews:
    fileid = orphan[0]

orphan (aka each element of the list previews) needs to be an array, in your case here it's an integer (aka non-subscriptable). The previews list is generated in my code with:

previews = sql_query("select tP.fileid, tP.name, tP.fullImgId from (select fileid, name, convert(substring_index(substring_index(path, '/', -2), '/', 1), UNSIGNED) as fullImgId from oc_filecache where path like '%/preview/%.jpg') as tP left join (select fileid from oc_filecache) as tA on tP.fullImgId = tA.fileid where tA.fileid is NULL order by tP.fullImgId", mydb)

Python unpacks the SQLite request response as a list of tuples, where each element is tP.fileid, tP.name, tP.fullImgId from your DB. Without having your code to look at, my guess is you changed the SQL query, so there is only one item left (most likely the fileid). In that case, you can either:


Sidenote: Python has 2 types of arrays, tuple which is immutable, and list which can be modified in many ways. As far as (read-only) item access is concerned, they are equivalent: elem = array[index].

aurelienpierre commented 1 month ago

Also I would be interested to see your Minio S3 code, maybe I can merge it here to broaden support.

d3v3l15h commented 1 month ago

Without having your code to look at, my guess is you changed the SQL query, so there is only one item left (most likely the fileid). In that case, you can either:

* restore the SQL query as in my code,

If you're referring to the query inside main.py, I didn't touch anything. Here(s the exact copy :

previews = sql_query("select tP.fileid, tP.name, tP.fullImgId from (select fileid, name, convert(substring_index(substring_index(path, '/', -2), '/', 1), UNSIGNED) as fullImgId from oc_filecache where path like '%/preview/%.jpg') as tP left join (select fileid from oc_filecache) as tA on tP.fullImgId = tA.fileid where tA.fileid is NULL order by tP.fullImgId", mydb)

If I execute this in SQL, I get the following result :

image

Seems OK to me so... what's wrong then ?

d3v3l15h commented 1 month ago

Also I would be interested to see your Minio S3 code, maybe I can merge it here to broaden support.

Below all the changes I had to do :

1) As my local MariaDB server is accessible through Unix Socket, I had the following error message "Host '127.0.0.1' is not allowed to connect to this MariaDB server". So, I added the following line in [mysql] section of config.toml file :

dbsocket = '/var/run/mysqld/mysqld.sock'

plus modified the connection part of main.py to use this new setting.

2) Final main.py including above change and settings needed to connect S3 Minio server is now :

config = toml.load("config.toml")

# Open server sessions
s3 = boto3.resource('s3',
                    endpoint_url='https://myminiohost.mydomain.com',
                    aws_access_key_id=config["s3"]["key"],
                    aws_secret_access_key=config["s3"]["secret"],
                    aws_session_token=None,
                    config=boto3.session.Config(signature_version='s3v4'),
                    region_name=config["s3"]["region"])

mybucket = s3.Bucket(config["s3"]["bucket"])

mydb = mysql.connector.connect(
  host = config["mysql"]["dbhost"],
  unix_socket = config["mysql"]["dbsocket"],
  user = config["mysql"]["dbuser"],
  password = config["mysql"]["dbpassword"],
  database = config["mysql"]["dbname"]
)

I hope it can be useful.