Update README and csv_uploader to match hardcoded field names
Remove --id-field and --seeding-field args from csv_uploader, hardcode field names as class constants, and fix the same PATCH/GET bugs. Update README examples to reflect simplified CLI args.
This commit is contained in:
19
README.md
19
README.md
@@ -16,10 +16,8 @@ python seed_tracker.py \
|
|||||||
--id-folder ./torrents \
|
--id-folder ./torrents \
|
||||||
--bt-backup ~/.local/share/qBittorrent/BT_backup \
|
--bt-backup ~/.local/share/qBittorrent/BT_backup \
|
||||||
--nocodb-url https://noco.example.com \
|
--nocodb-url https://noco.example.com \
|
||||||
--table-id tblXXXXX \
|
--table-id xxxxxxxxxxxxx \
|
||||||
--api-token xc-xxxx \
|
--api-token xc-xxxx
|
||||||
--id-field cXXXXX \
|
|
||||||
--seeding-field cYYYYY
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### CSV Mode (outputs file for manual import)
|
### CSV Mode (outputs file for manual import)
|
||||||
@@ -38,10 +36,8 @@ python seed_tracker.py \
|
|||||||
| `--id-folder` | Yes | Folder containing `{id}.torrent` files |
|
| `--id-folder` | Yes | Folder containing `{id}.torrent` files |
|
||||||
| `--bt-backup` | Yes | qBittorrent's `BT_backup` folder |
|
| `--bt-backup` | Yes | qBittorrent's `BT_backup` folder |
|
||||||
| `--nocodb-url` | API mode | NocoDB base URL |
|
| `--nocodb-url` | API mode | NocoDB base URL |
|
||||||
| `--table-id` | API mode | Table ID (starts with `tbl`) |
|
| `--table-id` | API mode | Table ID |
|
||||||
| `--api-token` | API mode | API token (`xc-token`) |
|
| `--api-token` | API mode | API token (`xc-token`) |
|
||||||
| `--id-field` | API mode | Field ID for Id column (starts with `c`) |
|
|
||||||
| `--seeding-field` | API mode | Field ID for seeding_users column (starts with `c`) |
|
|
||||||
| `--csv-only` | No | Skip API, output CSV instead |
|
| `--csv-only` | No | Skip API, output CSV instead |
|
||||||
| `--output` | No | CSV output path (default: `seeding_update.csv`) |
|
| `--output` | No | CSV output path (default: `seeding_update.csv`) |
|
||||||
| `--debug` | No | Print API request/response details |
|
| `--debug` | No | Print API request/response details |
|
||||||
@@ -49,7 +45,6 @@ python seed_tracker.py \
|
|||||||
## Finding NocoDB IDs
|
## Finding NocoDB IDs
|
||||||
|
|
||||||
- **Table ID**: Click `...` next to table name → Copy Table ID
|
- **Table ID**: Click `...` next to table name → Copy Table ID
|
||||||
- **Field IDs**: Click field header dropdown → Copy Field ID
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -63,10 +58,8 @@ Uploads CSV files generated by others (via `--csv-only`) to NocoDB.
|
|||||||
python csv_uploader.py \
|
python csv_uploader.py \
|
||||||
--csv seeds.csv \
|
--csv seeds.csv \
|
||||||
--nocodb-url https://noco.example.com \
|
--nocodb-url https://noco.example.com \
|
||||||
--table-id tblXXXXX \
|
--table-id xxxxxxxxxxxxx \
|
||||||
--api-token xc-xxxx \
|
--api-token xc-xxxx
|
||||||
--id-field cXXXXX \
|
|
||||||
--seeding-field cYYYYY
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Flags
|
## Flags
|
||||||
@@ -77,5 +70,3 @@ python csv_uploader.py \
|
|||||||
| `--nocodb-url` | Yes | NocoDB base URL |
|
| `--nocodb-url` | Yes | NocoDB base URL |
|
||||||
| `--table-id` | Yes | Table ID |
|
| `--table-id` | Yes | Table ID |
|
||||||
| `--api-token` | Yes | API token |
|
| `--api-token` | Yes | API token |
|
||||||
| `--id-field` | Yes | Field ID for Id column |
|
|
||||||
| `--seeding-field` | Yes | Field ID for seeding_users column |
|
|
||||||
|
|||||||
@@ -18,13 +18,13 @@ from pathlib import Path
|
|||||||
class NocoDBClient:
|
class NocoDBClient:
|
||||||
"""Simple NocoDB API client."""
|
"""Simple NocoDB API client."""
|
||||||
|
|
||||||
def __init__(self, base_url: str, table_id: str, api_token: str,
|
ID_FIELD = "Id"
|
||||||
id_field: str, seeding_field: str):
|
SEEDING_FIELD = "Seeding Users"
|
||||||
|
|
||||||
|
def __init__(self, base_url: str, table_id: str, api_token: str):
|
||||||
self.base_url = base_url.rstrip('/')
|
self.base_url = base_url.rstrip('/')
|
||||||
self.table_id = table_id
|
self.table_id = table_id
|
||||||
self.api_token = api_token
|
self.api_token = api_token
|
||||||
self.id_field = id_field
|
|
||||||
self.seeding_field = seeding_field
|
|
||||||
self.endpoint = f"{self.base_url}/api/v2/tables/{table_id}/records"
|
self.endpoint = f"{self.base_url}/api/v2/tables/{table_id}/records"
|
||||||
|
|
||||||
def _request(self, method: str, data: dict | None = None, params: dict | None = None) -> dict:
|
def _request(self, method: str, data: dict | None = None, params: dict | None = None) -> dict:
|
||||||
@@ -52,16 +52,16 @@ class NocoDBClient:
|
|||||||
|
|
||||||
def get_record(self, record_id: int | str) -> dict | None:
|
def get_record(self, record_id: int | str) -> dict | None:
|
||||||
try:
|
try:
|
||||||
params = {"where": f"({self.id_field},eq,{record_id})", "limit": "1"}
|
params = {"where": f"({self.ID_FIELD},eq,{record_id})", "limit": "1"}
|
||||||
result = self._request("GET", params=params)
|
result = self._request("GET", params=params)
|
||||||
records = result.get("list", [])
|
records = result.get("list", [])
|
||||||
return records[0] if records else None
|
return records[0] if records else None
|
||||||
except Exception:
|
except Exception:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def update_record(self, record_id: int | str, value: str) -> bool:
|
def update_record(self, row_id: int, value: str) -> bool:
|
||||||
try:
|
try:
|
||||||
data = {self.id_field: int(record_id), self.seeding_field: value}
|
data = {"Id": row_id, self.SEEDING_FIELD: value}
|
||||||
self._request("PATCH", data=data)
|
self._request("PATCH", data=data)
|
||||||
return True
|
return True
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@@ -94,8 +94,7 @@ def main():
|
|||||||
epilog="""
|
epilog="""
|
||||||
Example:
|
Example:
|
||||||
%(prog)s --csv seeds.csv --nocodb-url https://noco.example.com \\
|
%(prog)s --csv seeds.csv --nocodb-url https://noco.example.com \\
|
||||||
--table-id tblXXX --api-token xc-xxx \\
|
--table-id xxxxxxxxxxxxx --api-token xc-xxx
|
||||||
--id-field cXXX --seeding-field cYYY
|
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -107,10 +106,6 @@ Example:
|
|||||||
help='Table ID')
|
help='Table ID')
|
||||||
parser.add_argument('--api-token', required=True, type=str,
|
parser.add_argument('--api-token', required=True, type=str,
|
||||||
help='API token')
|
help='API token')
|
||||||
parser.add_argument('--id-field', required=True, type=str,
|
|
||||||
help='Field ID for Id column')
|
|
||||||
parser.add_argument('--seeding-field', required=True, type=str,
|
|
||||||
help='Field ID for seeding_users column')
|
|
||||||
|
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
@@ -126,10 +121,7 @@ Example:
|
|||||||
print(f"Loaded {len(rows)} rows from {args.csv}")
|
print(f"Loaded {len(rows)} rows from {args.csv}")
|
||||||
|
|
||||||
# Connect
|
# Connect
|
||||||
noco = NocoDBClient(
|
noco = NocoDBClient(args.nocodb_url, args.table_id, args.api_token)
|
||||||
args.nocodb_url, args.table_id, args.api_token,
|
|
||||||
args.id_field, args.seeding_field
|
|
||||||
)
|
|
||||||
|
|
||||||
print("Testing connection...")
|
print("Testing connection...")
|
||||||
try:
|
try:
|
||||||
@@ -157,7 +149,7 @@ Example:
|
|||||||
stats['not_found'] += 1
|
stats['not_found'] += 1
|
||||||
continue
|
continue
|
||||||
|
|
||||||
current = parse_multiselect(record.get(noco.seeding_field))
|
current = parse_multiselect(record.get(noco.SEEDING_FIELD))
|
||||||
|
|
||||||
if username in current:
|
if username in current:
|
||||||
print(f" = {record_id}: already listed")
|
print(f" = {record_id}: already listed")
|
||||||
@@ -166,7 +158,7 @@ Example:
|
|||||||
|
|
||||||
current.add(username)
|
current.add(username)
|
||||||
|
|
||||||
if noco.update_record(record_id, format_multiselect(current)):
|
if noco.update_record(record["Id"], format_multiselect(current)):
|
||||||
print(f" + {record_id}: added {username}")
|
print(f" + {record_id}: added {username}")
|
||||||
stats['updated'] += 1
|
stats['updated'] += 1
|
||||||
else:
|
else:
|
||||||
|
|||||||
Reference in New Issue
Block a user