Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
91 changes: 69 additions & 22 deletions classes/CSteamSharedFile.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ SteamCommunity.prototype.getSteamSharedFile = function(sharedFileId, callback) {
fileSize: null,
postDate: null,
resolution: null,
categories: [],
tags: [],
uniqueVisitorsCount: null,
favoritesCount: null,
upvoteCount: null,
Expand All @@ -39,6 +41,27 @@ SteamCommunity.prototype.getSteamSharedFile = function(sharedFileId, callback) {
// Load output into cheerio to make parsing easier
let $ = Cheerio.load(body);


// Determine type by looking at the second breadcrumb. Find the first separator as it has a unique name and go to the next element which holds our value of interest
let breadcrumb = $(".breadcrumbs > .breadcrumb_separator").next().get(0).children[0].data || "";

if (breadcrumb.includes("Screenshot")) {
sharedfile.type = ESharedFileType.Screenshot;
}

if (breadcrumb.includes("Artwork")) {
sharedfile.type = ESharedFileType.Artwork;
}

if (breadcrumb.includes("Guide")) {
sharedfile.type = ESharedFileType.Guide;
}

if (breadcrumb.includes("Workshop")) {
sharedfile.type = ESharedFileType.Workshop;
}


// Dynamically map detailsStatsContainerLeft to detailsStatsContainerRight in an object to make readout easier. It holds size, post date and resolution.
let detailsStatsObj = {};
let detailsLeft = $(".detailsStatsContainerLeft").children();
Expand All @@ -52,6 +75,7 @@ SteamCommunity.prototype.getSteamSharedFile = function(sharedFileId, callback) {
detailsStatsObj[detailsLeft[e].children[0].data.trim()] = detailsRight[e].children[0].data;
});


// Dynamically map stats_table descriptions to values. This holds Unique Visitors and Current Favorites
let statsTableObj = {};
let statsTable = $(".stats_table").children();
Expand Down Expand Up @@ -82,8 +106,28 @@ SteamCommunity.prototype.getSteamSharedFile = function(sharedFileId, callback) {
sharedfile.postDate = Helpers.decodeSteamTime(posted);


// Find resolution if artwork or screenshot
sharedfile.resolution = detailsStatsObj["Size"] || null;
// Find resolution if artwork or screenshot. Guides don't have a resolution and workshop items display it somewhere else
if (sharedfile.type != ESharedFileType.Workshop) {
sharedfile.resolution = detailsStatsObj["Size"] || null;
} else {
let resolutionTag = $(".workshopTagsTitle:contains(\"Resolution:\")").next();

sharedfile.resolution = resolutionTag.text() || null; // Keep prop null if this workshop item does not have a resolution
}


// Find categories if guide or workshop item
if (sharedfile.type == ESharedFileType.Guide || sharedfile.type == ESharedFileType.Workshop) {
let categoryTag = $(".workshopTagsTitle:contains(\"Category:\")").parent().contents().slice(1).text(); // Find div containing 'Category:' workshopTagsTitle, remove first element 'Category:' and get everything else as text

sharedfile.categories = categoryTag ? categoryTag.split(", ") : []; // Convert to array if string is not empty (aka no categories have been found)
}


// Find tags (there can be multiple)
let tagsTag = $(".workshopTagsTitle:contains(\"Tags:\")").next().contents();

sharedfile.tags = tagsTag.map((i, e) => e.type === 'text' ? $(e).text() : '').get() || []; // Map text to an array - https://stackoverflow.com/a/31543727


// Find uniqueVisitorsCount. We can't use ' || null' here as Number("0") casts to false
Expand Down Expand Up @@ -113,24 +157,11 @@ SteamCommunity.prototype.getSteamSharedFile = function(sharedFileId, callback) {


// Determine if this account has already voted on this sharedfile
sharedfile.isUpvoted = String($(".workshopItemControlCtn > #VoteUpBtn")[0].attribs["class"]).includes("toggled"); // Check if upvote btn class contains "toggled"
sharedfile.isDownvoted = String($(".workshopItemControlCtn > #VoteDownBtn")[0].attribs["class"]).includes("toggled"); // Check if downvote btn class contains "toggled"
const voteUpBtn = $(".workshopItemControlCtn > #VoteUpBtn")[0] || $(".greenlight_controls > #VoteUpBtn")[0]; // workshopItemControlCtn for "normal" items, greenlight_controls for items which can be voted into a game (e.g. CS skins)
const voteDownBtn = $(".workshopItemControlCtn > #VoteDownBtn")[0] || $(".greenlight_controls > #VoteDownBtn")[0];


// Determine type by looking at the second breadcrumb. Find the first separator as it has a unique name and go to the next element which holds our value of interest
let breadcrumb = $(".breadcrumbs > .breadcrumb_separator").next().get(0).children[0].data || "";

if (breadcrumb.includes("Screenshot")) {
sharedfile.type = ESharedFileType.Screenshot;
}

if (breadcrumb.includes("Artwork")) {
sharedfile.type = ESharedFileType.Artwork;
}

if (breadcrumb.includes("Guide")) {
sharedfile.type = ESharedFileType.Guide;
}
sharedfile.isUpvoted = String(voteUpBtn.attribs["class"]).includes("toggled"); // Check if upvote btn class contains "toggled"
sharedfile.isDownvoted = String(voteDownBtn.attribs["class"]).includes("toggled"); // Check if downvote btn class contains "toggled"


// Find owner profile link, convert to steamID64 using SteamIdResolver lib and create a SteamID object
Expand Down Expand Up @@ -158,7 +189,7 @@ SteamCommunity.prototype.getSteamSharedFile = function(sharedFileId, callback) {
* Constructor - Creates a new SharedFile object
* @class
* @param {SteamCommunity} community
* @param {{ id: string, type: ESharedFileType, appID: number, owner: SteamID|null, fileSize: string|null, postDate: number, resolution: string|null, uniqueVisitorsCount: number, favoritesCount: number, upvoteCount: number|null, guideNumRatings: Number|null, isUpvoted: boolean, isDownvoted: boolean }} data
* @param {{ id: string, type: ESharedFileType, appID: number, owner: SteamID|null, fileSize: string|null, postDate: number, resolution: string|null, category: string[], tags: string[], uniqueVisitorsCount: number, favoritesCount: number, upvoteCount: number|null, guideNumRatings: Number|null, isUpvoted: boolean, isDownvoted: boolean }} data
*/
function CSteamSharedFile(community, data) {
/**
Expand Down Expand Up @@ -200,7 +231,7 @@ CSteamSharedFile.prototype.comment = function(message, callback) {
* Subscribes to this sharedfile's comment section. Note: Checkbox on webpage does not update
* @param {function} callback - Takes only an Error object/null as the first argument
*/
CSteamSharedFile.prototype.subscribe = function(callback) {
CSteamSharedFile.prototype.subscribeComments = function(callback) {
this._community.subscribeSharedFileComments(this.owner, this.id, callback);
};

Expand All @@ -216,6 +247,22 @@ CSteamSharedFile.prototype.unfavorite = function(callback) {
* Unsubscribes from this sharedfile's comment section. Note: Checkbox on webpage does not update
* @param {function} callback - Takes only an Error object/null as the first argument
*/
CSteamSharedFile.prototype.unsubscribe = function(callback) {
CSteamSharedFile.prototype.unsubscribeComments = function(callback) {
this._community.unsubscribeSharedFileComments(this.owner, this.id, callback);
};

/**
* Subscribes to this workshop item
* @param {function} callback - Takes only an Error object/null as the first argument
*/
CSteamSharedFile.prototype.subscribeWorkshop = function(callback) {
this._community.subscribeWorkshopSharedFile(this.id, this.appID, callback);
};

/**
* Unsubscribes from this workshop item
* @param {function} callback - Takes only an Error object/null as the first argument
*/
CSteamSharedFile.prototype.unsubscribeWorkshop = function(callback) {
this._community.unsubscribeWorkshopSharedFile(this.id, this.appID, callback);
};
48 changes: 47 additions & 1 deletion components/sharedfiles.js
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ SteamCommunity.prototype.unfavoriteSharedFile = function(sharedFileId, appid, ca
};

/**
* Unsubscribes from a sharedfile's comment section. Note: Checkbox on webpage does not update
* Unsubscribes from a sharedfile's comment section.
* @param {SteamID | String} userID - ID of the user associated to this sharedfile
* @param {String} sharedFileId - ID of the sharedfile
* @param {function} callback - Takes only an Error object/null as the first argument
Expand All @@ -156,3 +156,49 @@ SteamCommunity.prototype.unsubscribeSharedFileComments = function(userID, shared
callback(err);
}, "steamcommunity");
};

/**
* Subscribes to a workshop item sharedfile.
* @param {String} sharedFileId - ID of the sharedfile
* @param {String} appid - ID of the app associated to this sharedfile
* @param {function} callback - Takes only an Error object/null as the first argument
*/
SteamCommunity.prototype.subscribeWorkshopSharedFile = function(sharedFileId, appid, callback) {
this.httpRequestPost({
"uri": "https://steamcommunity.com/sharedfiles/subscribe",
"form": {
"id": sharedFileId,
"appid": appid,
"sessionid": this.getSessionID()
}
}, function(err, response, body) {
if (!callback) {
return;
}

callback(err);
}, "steamcommunity");
};

/**
* Unsubscribes from a workshop item sharedfile.
* @param {String} sharedFileId - ID of the sharedfile
* @param {String} appid - ID of the app associated to this sharedfile
* @param {function} callback - Takes only an Error object/null as the first argument
*/
SteamCommunity.prototype.unsubscribeWorkshopSharedFile = function(sharedFileId, appid, callback) {
this.httpRequestPost({
"uri": "https://steamcommunity.com/sharedfiles/unsubscribe",
"form": {
"id": sharedFileId,
"appid": appid,
"sessionid": this.getSessionID()
}
}, function(err, response, body) {
if (!callback) {
return;
}

callback(err);
}, "steamcommunity");
};
4 changes: 3 additions & 1 deletion resources/ESharedFileType.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@ module.exports = {
"Screenshot": 0,
"Artwork": 1,
"Guide": 2,
"Workshop": 3,

// Value-to-name mapping for convenience
"0": "Screenshot",
"1": "Artwork",
"2": "Guide"
"2": "Guide",
"3": "Workshop"
};