-
Notifications
You must be signed in to change notification settings - Fork 5.5k
10808 bitportio #18700
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
10808 bitportio #18700
Conversation
- Introduced `Add Item` action for adding torrents with optional folder selection. - Added `Search` action to find files and folders in the cloud. - Implemented utility function `prepareList` for organizing folder and file data. - Updated `bitport.app.mjs` to include new prop definitions and methods for folder management. - Created new sources for detecting new files and media, enhancing event-driven capabilities. - Bumped package version to 0.1.0 and added necessary dependencies.
|
The latest updates on your projects. Learn more about Vercel for GitHub. 2 Skipped Deployments
|
WalkthroughAdds a Bitport integration: core app with API helpers and folder selection, two actions (Search, Add Item), a prepareList utility, a reusable polling base source, two concrete sources (New File, New Media) with sample events, and package metadata/dependency updates. Changes
Sequence Diagram(s)sequenceDiagram
autonumber
actor User
participant Action as Add Item Action
participant App as Bitport App
participant API as Bitport API
User->>Action: provide `torrent` (+ optional `folderCode`)
Action->>App: addItem({ torrent, folder_code })
App->>API: POST /v2/transfers
API-->>App: 201 Created + transfer data
App-->>Action: response
Action-->>User: export "$summary" + data
sequenceDiagram
autonumber
actor User
participant Action as Search Action
participant App as Bitport App
participant API as Bitport API
User->>Action: provide `query`
Action->>App: search({ query })
App->>API: GET /v2/search/{query}
API-->>App: 200 OK + results
App-->>Action: { folders, files }
Action-->>User: export "$summary" + data
sequenceDiagram
autonumber
participant Timer as Timer
participant Source as Base Source
participant App as Bitport App
participant API as Bitport API
participant Util as prepareList
participant Stream as Event Stream
Timer-->>Source: tick() / deploy()
Source->>App: listFiles({ folderPathBase64, maxResults? })
App->>API: GET /v2/cloud/byPath
API-->>App: 200 OK + tree
App-->>Source: tree
Source->>Util: prepareList(items, filesOnly: true)
Util-->>Source: flattened files
Source->>Source: filter by date (> lastDate) and optional getFilter
Source->>Source: sort desc, cap to maxResults, update lastDate
loop emit oldest -> newest
Source-->>Stream: emit({ id, summary, ts })
end
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning, 1 inconclusive)
✅ Passed checks (3 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 6
🧹 Nitpick comments (6)
components/bitport/sources/new-media/test-event.mjs (1)
1-22: Note: Identical test event.This test event is identical to
components/bitport/sources/new-file/test-event.mjs. If both sources (New File and New Media) are meant to emit the same event structure, this duplication is acceptable. Otherwise, consider whether New Media should filter by media types or use a different sample.components/bitport/common/utils.mjs (2)
8-11: Consider adding null checks for item.files.If
item.filesis undefined or null, the spread operator will throw a runtime error.Apply this diff:
if (filesOnly) { itemsArray.push( - ...item.files, + ...(item.files || []), ); } else {
19-23: Consider adding null checks for item.folders.If
item.foldersis undefined or null, the recursive call and iteration will fail.Apply this diff:
itemsArray.push(...prepareList({ - items: item.folders, + items: item.folders || [], parentName: fullName, filesOnly, }));components/bitport/bitport.app.mjs (1)
205-231: Consider removing or documenting commented paginate helper.The commented-out
paginateasync generator helper is either incomplete or for future use. Consider removing it if not needed, or adding a TODO comment explaining its purpose.components/bitport/actions/search/search.mjs (1)
17-29: Consider adding defensive checks for response structure.If the API returns an error or the response structure is unexpected, accessing
data.folders.lengthon Line 23 will throw a runtime error.Apply this diff to add basic null checks:
const { data } = await this.app.search({ $, query: this.query, }); - $.export("$summary", `Successfully found for ${data.folders.length} folder${data.folders.length > 1 + const folderCount = data?.folders?.length || 0; + const fileCount = data?.files?.length || 0; + $.export("$summary", `Successfully found ${folderCount} folder${folderCount > 1 ? "s" - : ""} and ${data.files.length} file${data.files.length > 1 + : ""} and ${fileCount} file${fileCount > 1 ? "s" : ""}`); return data;components/bitport/sources/common/base.mjs (1)
52-55: Optimize date parsing in sort comparator.The sort comparator calls
Date.parse()twice for every comparison. Consider parsing dates once and caching, or sorting by the pre-parsed values.Apply this diff for more efficient sorting:
if (items.length) { - items = items.filter((item) => { - return Date.parse(item.created_at.date) > lastDate; - }) - .sort((a, b) => Date.parse(b.created_at.date) - Date.parse(a.created_at.date)); + items = items + .map((item) => ({ + ...item, + _timestamp: Date.parse(item.created_at.date), + })) + .filter((item) => item._timestamp > lastDate) + .sort((a, b) => b._timestamp - a._timestamp);
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (10)
components/bitport/actions/add-item/add-item.mjs(1 hunks)components/bitport/actions/search/search.mjs(1 hunks)components/bitport/bitport.app.mjs(1 hunks)components/bitport/common/utils.mjs(1 hunks)components/bitport/package.json(2 hunks)components/bitport/sources/common/base.mjs(1 hunks)components/bitport/sources/new-file/new-file.mjs(1 hunks)components/bitport/sources/new-file/test-event.mjs(1 hunks)components/bitport/sources/new-media/new-media.mjs(1 hunks)components/bitport/sources/new-media/test-event.mjs(1 hunks)
🧰 Additional context used
🧬 Code graph analysis (4)
components/bitport/common/utils.mjs (1)
components/bitport/sources/common/base.mjs (1)
items(46-49)
components/bitport/sources/new-media/new-media.mjs (1)
components/bitport/sources/common/base.mjs (1)
items(46-49)
components/bitport/sources/common/base.mjs (2)
components/bitport/actions/add-item/add-item.mjs (1)
response(25-31)components/bitport/common/utils.mjs (2)
prepareList(1-27)prepareList(1-27)
components/bitport/bitport.app.mjs (1)
components/bitport/common/utils.mjs (2)
prepareList(1-27)prepareList(1-27)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
- GitHub Check: Verify TypeScript components
- GitHub Check: Publish TypeScript components
- GitHub Check: pnpm publish
- GitHub Check: Lint Code Base
🔇 Additional comments (16)
components/bitport/sources/new-file/test-event.mjs (1)
1-22: LGTM!The test event structure appears consistent with the Bitport API response format for file metadata.
components/bitport/package.json (2)
3-3: LGTM!Version bump to 0.1.0 is appropriate for the new features being added (sources and actions).
15-16: LGTM!The dependency on
@pipedream/platformversion 3.1.0 is correct and aligns with the latest stable release.Based on learnings.
components/bitport/sources/new-file/new-file.mjs (1)
1-19: LGTM!The source module follows Pipedream conventions correctly, extending the common base and providing a custom summary method.
components/bitport/bitport.app.mjs (3)
1-2: LGTM!The imports are correct, using the
axioshelper from@pipedream/platformand the localprepareListutility.
26-42: LGTM!The API helper methods (
_apiUrl,_getHeaders,_makeRequest) follow Pipedream conventions correctly and use the OAuth access token fromthis.$auth.
43-57: LGTM!The
search,listFolders, andaddItemmethods correctly use the internal request helper to call the Bitport API endpoints.components/bitport/actions/add-item/add-item.mjs (1)
1-36: LGTM!The action follows Pipedream conventions correctly, properly using the app's
addItemmethod and exporting a summary.components/bitport/sources/new-media/new-media.mjs (3)
1-2: LGTM!Import statements are correct and follow the standard pattern for Pipedream component extensions.
4-11: LGTM!Component metadata is properly configured with appropriate dedupe strategy for a polling source.
12-26: LGTM!The
getFilterandgetSummarymethods correctly implement media-specific filtering and event formatting.components/bitport/sources/common/base.mjs (5)
1-3: LGTM!Import statements are correct and use appropriate platform utilities.
5-22: LGTM!Props are properly configured for a polling source with appropriate timer interval and folder selection.
78-85: LGTM!The deploy hook and run method follow the standard pattern for Pipedream polling sources, with deploy loading an initial batch of historical events.
36-37: Confirm encoding the correct folderCode property
Encodingthis.folderCode.labeltargets the display name, not the folder identifier. Verify thatfolderCodeexposes an ID property (e.g.,.value) and use that (or the rawfolderCode) when Base64-encoding.
39-55: Client-side date filtering is correct: Bitport API has no server-side date filter for listFiles; local filtering is required.
- Removed the `foldersOnly` option from the `prepareList` function. - Deleted the `listFiles` method to streamline file management. - Updated the `listFolders` method call for improved folder handling. - Added `annotations` to `Add Item` and `Search` actions for better metadata. - Adjusted timestamp parsing to ensure consistency across data handling.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (4)
components/bitport/actions/add-item/add-item.mjs(1 hunks)components/bitport/actions/search/search.mjs(1 hunks)components/bitport/bitport.app.mjs(1 hunks)components/bitport/sources/common/base.mjs(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
- components/bitport/sources/common/base.mjs
- components/bitport/actions/search/search.mjs
🧰 Additional context used
🧬 Code graph analysis (1)
components/bitport/bitport.app.mjs (2)
components/bitport/common/utils.mjs (2)
prepareList(1-27)prepareList(1-27)components/spotify/actions/get-album-tracks/get-album-tracks.mjs (1)
axios(53-56)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
- GitHub Check: pnpm publish
- GitHub Check: Verify TypeScript components
- GitHub Check: Publish TypeScript components
- GitHub Check: Lint Code Base
🔇 Additional comments (4)
components/bitport/bitport.app.mjs (2)
15-20: LGTM! Parameter mismatch from previous review has been fixed.The previous review flagged an incorrect
foldersOnly: trueparameter. This has been correctly resolved by relying on the defaultfilesOnly = falseinprepareList, which returns folder objects with thefullNameproperty needed for the folder selector.
25-64: LGTM! Clean API helper implementation.The API helper methods (
_apiUrl,_getHeaders,_makeRequest,search,listFolders,addItem) follow Pipedream conventions and properly use the axios helper from@pipedream/platform. The removal of the hardcoded mock data from the previouslistFilesmethod also addresses a critical issue from the past review.components/bitport/actions/add-item/add-item.mjs (2)
9-13: LGTM! Annotations added as requested.The previous review flagged missing annotations. These have been correctly added with appropriate values:
destructiveHint: false- adding a torrent is not destructiveopenWorldHint: true- action calls external Bitport APIreadOnlyHint: false- action creates a new transfer
29-40: LGTM! Clean action implementation.The action properly:
- Calls
this.app.addItem()with the Pipedream step context$- Converts the camelCase prop
folderCodeto snake_casefolder_codeas expected by the API- Exports a user-friendly summary message
- Returns the API response
| async options() { | ||
| const { data } = await this.listFolders(); | ||
|
|
||
| return prepareList({ | ||
| items: data, | ||
| }).map((item) => ({ | ||
| label: item.fullName, | ||
| value: item.code, | ||
| })); | ||
| }, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
Verify the API response structure for folder listing.
The code destructures data from the listFolders() response on line 13. Ensure that the Bitport API actually returns an object with a data property. If the API returns the folder array directly (without wrapping it in a data property), this will fail.
Run the following script to check the actual API response structure:
Alternatively, please search the web for the Bitport API documentation:
🏁 Script executed:
#!/bin/bash
# Description: Search for API response examples or tests that show the structure
# Search for any test files or documentation about the listFolders response
rg -n -A10 -B3 'cloud/byPath|listFolders' --type=js
# Search for any example responses or mock data
rg -n -A10 'status.*success.*data' --type=json --type=jsLength of output: 0
🌐 Web query:
What is the response structure of the Bitport.io API endpoint GET /v2/cloud/byPath with scope=recursive parameter?
💡 Result:
Top-level wrapper
- status: "success" | "error"
- data: object (on success)
- errors: null | array
When calling GET /v2/cloud/byPath?scope=recursive the data object contains the folder metadata plus recursive lists of folders and files. Skeleton (fields shown from Bitport docs):
{
"status": "success",
"data": {
"name": "",
"code": "<folder code|null>",
"size": ,
"folders": [
{
"name": "",
"code": "",
"size": "",
"created_at": { "date": "YYYY-MM-DD HH:MM:SS.000000", "timezone_type": 3, "timezone": "UTC" },
"files_count": ""
},
...
],
"files": [
{
"name": "",
"crc32": ,
"created_at": { "date": "YYYY-MM-DD HH:MM:SS.000000", "timezone_type": 3, "timezone": "UTC" },
"code": "",
"parent_folder_code": "",
"size": ,
"video": true|false,
"conversion_status": "",
"screenshots": { "small": "", "medium": "", "big": "" },
"extension": "",
"type": "<video|music|archive|...>",
"paused_at": ,
"virus": true|false
},
...
]
},
"errors": null
}
Source: Bitport API docs for cloud endpoints and file-byPath examples. [1][2]
References
[1] Bitport API — /v2/cloud (example recursive response).
[2] Bitport API — /v2/files/byPath (file object structure).
Extract the folders array from the API response
The Bitport endpoint returns { status, data: { folders: [...], files: […] } }, so const { data } = await this.listFolders() yields an object, not an array. Update to:
const { data: { folders } } = await this.listFolders();
return prepareList({ items: folders }).map(/* … */);🤖 Prompt for AI Agents
In components/bitport/bitport.app.mjs around lines 12 to 21, the code
destructures the API response as const { data } = await this.listFolders(), but
the endpoint returns data: { folders: [...], files: [...] } so data is an object
not an array; change the destructure to extract folders (const { data: { folders
} } = await this.listFolders()) and pass folders into prepareList (prepareList({
items: folders })) then map over the resulting list to return label/value
objects.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, Ready for QA!
Resolves #10808
Summary by CodeRabbit