├── .github └── FUNDING.yml ├── .gitignore ├── README.md ├── api ├── README.md ├── events │ └── manyvids.json ├── index.js ├── manyvids.js ├── middleware │ └── middleware.js ├── package-lock.json ├── package.json ├── routes │ ├── adultempire │ │ ├── adultempireHelper.js │ │ └── index.js │ ├── aebn │ │ ├── aebnHelper.js │ │ └── index.js │ ├── azure │ │ ├── azureHelper.js │ │ └── index.js │ ├── clipnuke │ │ ├── cnHelper.js │ │ ├── index.js │ │ └── upload │ │ │ ├── index.js │ │ │ └── uploadHelper.js │ ├── clips4sale │ │ ├── c4sHelper.js │ │ ├── cookie.json │ │ ├── ftp │ │ │ ├── ftpHelper.js │ │ │ └── index.js │ │ ├── index.js │ │ ├── postClip.js │ │ └── sales │ │ │ ├── index.js │ │ │ └── salesHelper.js │ ├── hotmovies │ │ ├── hotmoviesHelper.js │ │ └── index.js │ ├── index.js │ ├── local │ │ └── index.js │ ├── manyvids │ │ ├── cookie.json │ │ ├── index.js │ │ ├── mvHelper.js │ │ ├── postVid.js │ │ └── putVid.js │ ├── woo │ │ ├── client.js │ │ ├── index.js │ │ └── wooHelper.js │ └── xvideos │ │ ├── index.js │ │ ├── postVideo.js │ │ └── xvHelper.js ├── server.cert ├── server.js ├── server.key └── webdriverio │ ├── client.js │ ├── config.js │ └── singleton.js ├── bin └── chromedriver.exe └── license.md /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] 4 | patreon: # Replace with a single Patreon username 5 | open_collective: # Replace with a single Open Collective username 6 | ko_fi: # Replace with a single Ko-fi username 7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 9 | liberapay: # Replace with a single Liberapay username 10 | issuehunt: # Replace with a single IssueHunt username 11 | otechie: # Replace with a single Otechie username 12 | lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry 13 | custom: ["https://clipnuke.com"] # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] 14 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | *.env* 3 | test* 4 | pornhub 5 | *.log 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Adult Content API 2 | 1. Install WebDriver 3 | 1. Configure the __.env__ files. 4 | 1. Open the /api directory in your command line shell. 5 | 1. ```$ npm install``` 6 | 1. ```$ npm start``` 7 | -------------------------------------------------------------------------------- /api/README.md: -------------------------------------------------------------------------------- 1 | # Usage 2 | Install project dependencies. 3 | ```bash 4 | $ npm install 5 | ``` 6 | 7 | Start the server. 8 | ```bash 9 | $ npm start 10 | -------------------------------------------------------------------------------- /api/events/manyvids.json: -------------------------------------------------------------------------------- 1 | [] 2 | -------------------------------------------------------------------------------- /api/index.js: -------------------------------------------------------------------------------- 1 | require('dotenv').config({ 2 | path: '.env.manyvids' 3 | }); 4 | const mv = require('./manyvids.js'); 5 | const webdriverio = require('webdriverio'); 6 | const options = { 7 | desiredCapabilities: { 8 | browserName: 'chrome' 9 | }, 10 | host: process.env.HOST || "http://localhost", 11 | port: process.env.PORT || 4444 12 | }; 13 | var client = webdriverio.remote(options); 14 | 15 | // A pre-authenticated test cookie 16 | var cookie = {"domain":".manyvids.com","expiry":1520927551.376236,"httpOnly":true,"name":"PHPSESSID","path":"/","secure":false,"value":"rb1kb7j0t2k1pbja6agg8trkd1"}; 17 | 18 | const params = { 19 | client: client, 20 | cookie: cookie 21 | }; 22 | 23 | // Login to ManyVids and get our session cookie 24 | mv.login(params, function(err, cookie) { 25 | console.log(process.argv[2]); 26 | var id = process.argv[2]; // Cli Arg (Is the "3rd" item in the process.argv array @see nodejs docs) 27 | 28 | mv.editVid(id, params, function(err, data) { 29 | console.log(data); 30 | }); 31 | 32 | }); 33 | -------------------------------------------------------------------------------- /api/manyvids.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Login to ManyVids. 3 | * Init a new webdriverio session. 4 | * @param {webdriverio} client A webdriverio client 5 | * @param {Function} callback err, data 6 | * @return {Object} A webdriverio cookie containing the authenticated PHPSESSID 7 | */ 8 | function auth(params, callback) { 9 | params.client 10 | .init() 11 | .url('https://www.manyvids.com/Login/') 12 | .waitForVisible('button.js-warning18-popup', 3000) 13 | .click('button.js-warning18-popup') 14 | .setValue('#triggerUsername', process.env.USER) 15 | .setValue('#triggerPassword', process.env.PASS) 16 | .click('#loginAccountSubmit') 17 | // .pause(15000) // Wait in case we need to solve a recaptcha. 18 | .getCookie('PHPSESSID').then(function(cookie) { 19 | console.log('Cookie is: ' + JSON.stringify(cookie)); 20 | return cookie; 21 | }) 22 | .next(function (data) { 23 | console.log(data); 24 | return callback(null, data); 25 | }).catch((e) => console.log(e)); 26 | }; 27 | 28 | /** 29 | * Edit Vid - Details 30 | * Sends a GET request to the server, using an authenticated webdriverio session, fetches the data, then ends the session. 31 | * NOTE: It's super important to use .end() method to end the browser session. Because {@link auth | auth} calls init() to open a new browser session. 32 | * IMPORTANT: If we don't run browser.end(), this app will fail when {@link getVid | getVid} or another method is called! 33 | * @param {Integer} id A ManyVids Video ID 34 | * @param {Object} params client, cookie 35 | * @param {Function} callback [description] 36 | * @return {Object} An object containing details about a ManyVids video. 37 | */ 38 | function editVid(id, params, callback) { 39 | var data = {}; 40 | data.video = {}; 41 | data.website = "MANYVIDS"; 42 | data.categories = []; 43 | console.log(id, params); 44 | 45 | params.client 46 | .setCookie(params.cookie) 47 | .url(`https://www.manyvids.com/Edit-vid/${id}/`) 48 | .pause(2000) 49 | 50 | // Manyvids Session Details 51 | .getAttribute('html', 'data-session-details').then(function(val) { 52 | console.log('Session Details: ' + JSON.stringify(val)); 53 | data.session = JSON.parse(val); 54 | data.remoteStudioId = data.session.user_id; 55 | }) 56 | 57 | // ManyVids Video ID 58 | .getAttribute('body', 'data-video-id').then(function(val) { 59 | console.log('Video ID: ' + JSON.stringify(val)); 60 | data.video.id = val; 61 | data.remoteId = data.video.id; 62 | }) 63 | 64 | // AWS eTag 65 | .getAttribute('body', 'data-etag').then(function(val) { 66 | console.log('eTag: ' + JSON.stringify(val)); 67 | data.video.etag = val; 68 | }) 69 | 70 | // Trailer Filename 71 | .getAttribute('body', 'data-filename').then(function(val) { 72 | console.log('Filename: ' + JSON.stringify(val)); 73 | data.video.filename = val; 74 | }) 75 | 76 | // Price 77 | .getValue('[name="video_cost"]').then(function(val) { 78 | console.log('Price is: ' + JSON.stringify(val*1)); 79 | data.price = val*1; 80 | }) 81 | 82 | // Video Title 83 | .getValue('[name="video_title"]').then(function(val) { 84 | console.log('Title is: ' + JSON.stringify(val)); 85 | data.name = val; 86 | }) 87 | 88 | // Description 89 | .getText('[name="video_description"]').then(function(val) { 90 | console.log('Title is: ' + JSON.stringify(val)); 91 | data.description = val; 92 | }) 93 | 94 | // Categories/"Tags" 95 | .getAttribute('//*[@id="videoSettings"]/div[1]/div/ul/li[1]/input', 'value').then(function(val) { 96 | if(val) { data.categories.push(val); } 97 | }) 98 | .getAttribute('//*[@id="videoSettings"]/div[1]/div/ul/li[2]/input', 'value').then(function(val) { 99 | if(val) { data.categories.push(val); } 100 | }) 101 | .getAttribute('//*[@id="videoSettings"]/div[1]/div/ul/li[3]/input', 'value').then(function(val) { 102 | if(val) { data.categories.push(val); } 103 | }) 104 | .getAttribute('//*[@id="videoSettings"]/div[1]/div/ul/li[4]/input', 'value').then(function(val) { 105 | if(val) { data.categories.push(val); } 106 | }) 107 | .getAttribute('//*[@id="videoSettings"]/div[1]/div/ul/li[5]/input', 'value').then(function(val) { 108 | if(val) { data.categories.push(val); } 109 | }) 110 | 111 | // Video Length 112 | .getAttribute('.js-video-length', 'data-video-length').then(function(val) { 113 | console.log(val); 114 | if(val * 1) { 115 | data.lengthSeconds = val * 1; 116 | } else { 117 | data.length = val; 118 | } 119 | }) 120 | 121 | // Intensity 122 | .execute(function(obj) { 123 | obj = jQuery('#intensity > option:selected')[0].value; 124 | return obj; 125 | }, data).then(function(obj) { 126 | console.log("Intensity", obj.value); 127 | data.intensity = obj.value; 128 | }) 129 | 130 | /** Local Error Callback 131 | * @todo Break on various errors 132 | * @return error message, {} 133 | */ 134 | .catch(function(err) { 135 | console.log('Local catch called'); 136 | return callback("Error fetching the vid details.", {}); 137 | }) 138 | 139 | // Sale/Discount % 140 | .execute(function(obj) { 141 | obj = jQuery('#sale > option:selected')[0].value; 142 | return obj; 143 | }, data).then(function(obj) { 144 | var discount = obj.value; 145 | console.log(`Discount ${discount}`); 146 | data.discount = discount; 147 | if (discount) { 148 | data.salePrice = data.price - ( ( discount / 100 ) * data.price ); 149 | } 150 | }) 151 | 152 | // Trailer URL 153 | .getAttribute('//*[@id="rmpPlayer"]', 'data-video-filepath').then(function(val) { 154 | data.poster = val; 155 | }) 156 | 157 | // Poster Img URL 158 | .getAttribute('//*[@id="rmpPlayer"]', 'data-video-screenshot').then(function(val) { 159 | data.trailer = val; 160 | }) 161 | 162 | /** CreatedAt Timestamp 163 | * Epoch milliseconds to UTC string 164 | */ 165 | .getAttribute('//*[@id="rmpPlayer"]', 'data-video-filepath').then(function(val) { 166 | var epochMs = 0; 167 | var d = new Date(0); // The 0 there is the key, which sets the date to the epoch 168 | // var val = "https://dntgjk0do84uu.cloudfront.net/364438/e1a1813a9e1abe9866c0b74118081a58/preview/1520188436784.mp4_480_1520188447.m3u8"; // test string 169 | var regex = /https:\/\/.*\/.*\/(\d{13}).mp4_\d{3,4}_\d{10}.m3u8/; // Regex search string 170 | var regex2 = /https:\/\/s3.amazonaws.com\/manyvids-data\/php_uploads\/preview_videos\/.*\/(\d{13})_preview.mp4/; // Regex search string 171 | 172 | if (regex.test(val)) { 173 | var match = regex.exec(val); 174 | epochMs = match[1]; 175 | } else if (regex2.test(val)) { 176 | var match = regex2.exec(val); 177 | epochMs = match[1]; 178 | } 179 | 180 | // var match = regex.exec(val); 181 | // var epochMs = match[1]; // Match regex group 1 182 | // console.log(match, epochMs); 183 | // console.log("Converting to UTC String"); 184 | // var d = new Date(0); // The 0 there is the key, which sets the date to the epoch 185 | d.setUTCMilliseconds(epochMs); // set the dat obj to the video creatiume time in epoch ms 186 | data.createdAt = d.toISOString(); // Convert to UTC timestamp 187 | }) 188 | 189 | // Success Callback 190 | .next(function() { 191 | params.client.end(); 192 | console.log('Done!'); 193 | console.log(JSON.stringify(data, null, 2)); 194 | return callback(null, data); 195 | }) 196 | 197 | // Global Error Callback 198 | .catch((e) => console.log(e)); 199 | }; 200 | 201 | module.exports = { 202 | login: auth, 203 | editVid: editVid 204 | }; 205 | -------------------------------------------------------------------------------- /api/middleware/middleware.js: -------------------------------------------------------------------------------- 1 | var cors = function (req, res, next) { 2 | // Website you wish to allow to connect 3 | res.setHeader('Access-Control-Allow-Origin', '*'); 4 | // Request methods you wish to allow 5 | res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE'); 6 | // Request headers you wish to allow 7 | res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type'); 8 | // Set to true if you need the website to include cookies in the requests sent 9 | // to the API (e.g. in case you use sessions) 10 | res.setHeader('Access-Control-Allow-Credentials', true); 11 | // Pass to next layer of middleware 12 | next(); 13 | } 14 | 15 | module.exports = { cors }; 16 | -------------------------------------------------------------------------------- /api/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "adult-clip-store-api", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "server.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [], 10 | "author": "Aiden Valentine ", 11 | "dependencies": { 12 | "@woocommerce/woocommerce-rest-api": "^1.0.1", 13 | "body-parser": "^1.18.2", 14 | "cookie-parser": "^1.4.6", 15 | "cors": "^2.8.5", 16 | "dateformat": "^3.0.3", 17 | "dateutil": "^0.1.0", 18 | "dotenv": "^5.0.1", 19 | "express": "^4.16.2", 20 | "express-bearer-token": "^2.4.0", 21 | "ftp": "^0.3.10", 22 | "graphql-request": "^1.5.1", 23 | "hashmap": "^2.3.0", 24 | "hyperquest": "^2.1.3", 25 | "minio": "^7.0.26", 26 | "request": "^2.83.0", 27 | "webdriverio": "^4.11.0", 28 | "winston": "^2.4.0", 29 | "winston-express-middleware": "^0.1.0" 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /api/routes/adultempire/adultempireHelper.js: -------------------------------------------------------------------------------- 1 | var hyperquest = require('hyperquest'); 2 | var fs = require('fs'); 3 | var path = require('path'); 4 | var Client = require('ftp'); 5 | var Minio = require('minio'); 6 | 7 | const conf = require(path.join(process.env.APPDATA, "clipnuke", "config.json")); 8 | 9 | function upload(event, callback) { 10 | 11 | var dstFile = path.basename(event.url); 12 | 13 | console.log('File: ', dstFile) 14 | 15 | function search(nameKey, myArray) { 16 | for (var i = 0; i < myArray.length; i++) { 17 | if (myArray[i].name === nameKey) { 18 | return myArray[i]; 19 | } 20 | } 21 | } 22 | 23 | var ftpClient = new Client(); 24 | 25 | ftpClient.connect({ 26 | host: 'uploads.adultempirecash.com', 27 | user: conf.settings.adultempire.user, 28 | password: conf.settings.adultempire.pass 29 | }); 30 | 31 | ftpClient.on('ready', function() { 32 | 33 | /* var src = request({ 34 | url: event.url, 35 | method: "HEAD" 36 | }, function(err, response, body) { 37 | console.log(response.headers); 38 | return response.headers; 39 | // process.exit(0); 40 | }); */ 41 | // console.log(size); 42 | 43 | ftpClient.list('/', function(err, data) { 44 | // console.log(JSON.stringify(data, null, 2)); // Debug 45 | if (err) { 46 | console.log(err); 47 | } 48 | var obj = search(dstFile, data); 49 | console.log(obj); 50 | // console.log('File Size: ' + obj.size + ' Bytes'); 51 | // console.log(src, obj.size); 52 | 53 | if (obj) { 54 | ftpClient.end(); 55 | console.log('File already exists on destination server\'s filesystem.'); 56 | callback(null, obj); 57 | // process.exit(0); 58 | } else { 59 | 60 | if (event.type == "video") { 61 | 62 | // Allow insecure TLS connections 63 | process.env['NODE_TLS_REJECT_UNAUTHORIZED'] = '0'; 64 | 65 | // Setup minio client 66 | var minioClient = new Minio.Client({ 67 | endPoint: conf.settings.s3.endpoint, 68 | port: conf.settings.s3.port, 69 | useSSL: true, 70 | accessKey: conf.settings.s3.access_key, 71 | secretKey: conf.settings.s3.secret_key 72 | }); 73 | 74 | var size = 0; 75 | 76 | // Grab our video file from an s3-compatible server and stream (dataStream) 77 | minioClient.getObject('vods', event.url, function(err, dataStream) { 78 | if (err) { 79 | return console.log(err) 80 | } 81 | dataStream.on('data', function(chunk) { 82 | size += chunk.length 83 | }) 84 | dataStream.on('end', function() { 85 | console.log('End. Total size = ' + size) 86 | }) 87 | dataStream.on('error', function(err) { 88 | console.log(err) 89 | }) 90 | 91 | console.time("upload"); 92 | 93 | // Pipe stream to destination FTP server 94 | ftpClient.put(dataStream, dstFile, function(err) { 95 | if (err) { 96 | console.log(err); 97 | } 98 | ftpClient.end(); 99 | console.timeEnd("upload"); 100 | console.log("Finished"); 101 | }); 102 | }); 103 | } else { 104 | 105 | // Grab from HTTP request and stream 106 | var stream = hyperquest(event.url); 107 | console.time("upload"); 108 | 109 | // Pipe stream to destination FTP server 110 | ftpClient.put(stream, dstFile, function(err) { 111 | if (err) { 112 | console.log(err); 113 | } 114 | ftpClient.end(); 115 | console.timeEnd("upload"); 116 | console.log("Finished"); 117 | }); 118 | } 119 | } 120 | }); 121 | 122 | }); 123 | 124 | var upload = function() { 125 | ftpClient.size(dstFile, function(err, size) { 126 | // Assuming the err is the file not existing, good enough for now 127 | // err.code will give the exact status code otherwise (550 is file not found) 128 | var stream = hyperquest('event.url'); 129 | if (err) { 130 | 131 | hyperquest('event.url').pipe(res)(function(res) { 132 | // console.log(stream); 133 | ftpClient.put(stream, dstFile, function(err) { 134 | if (err) { 135 | console.log(err); 136 | } 137 | ftpClient.end(); 138 | console.timeEnd("upload"); 139 | console.log("Finished"); 140 | }); 141 | }); 142 | 143 | } else { 144 | 145 | console.log("Resuming download at start: " + size); 146 | getFileFromS3(size, function(res) { 147 | 148 | ftpClient.append(res, dstFile, function(err) { 149 | if (err) { 150 | console.log(err); 151 | } 152 | 153 | ftpClient.end(); 154 | console.timeEnd("upload"); 155 | console.log("Finished"); 156 | }); 157 | }); 158 | 159 | } 160 | }); 161 | }; 162 | 163 | ftpClient.on('close', function(hadError) { 164 | if (hadError) { 165 | console.log("FTP server closed with an error"); 166 | // callback("FTP server closed with an error"); 167 | } else { 168 | console.log("FTP server closed"); 169 | // done(); 170 | } 171 | }); 172 | 173 | ftpClient.on('error', function(err) { 174 | console.log("FTP server had error: " + err); 175 | }); 176 | 177 | 178 | ftpClient.on('end', function() { 179 | console.log("FTP server ended connection"); 180 | }); 181 | 182 | ftpClient.on('greeting', function(msg) { 183 | console.log(msg); 184 | }); 185 | 186 | } 187 | 188 | function httpUpload(event, callback) { 189 | 190 | var dstFile = path.basename(event.url); 191 | var ext = path.extname(event.url); 192 | var dstPath; 193 | if (ext == ".mp4" || ".wmv" || ".mov" || ".avi") { 194 | dstPath = '/clips'; 195 | } else if (ext == ".jpg" || ".gif" || ".png" || ".jpeg" || ".tiff" || ".tif") { 196 | dstPath = '/clip_images'; 197 | } 198 | switch (event.type) { 199 | case "trailer": 200 | dstPath = '/clips_previews'; 201 | break; 202 | case "video": 203 | dstPath = '/clips'; 204 | break; 205 | case "poster": 206 | dstPath = '/clip_images'; 207 | break; 208 | } 209 | console.log('File: ', dstFile) 210 | 211 | function search(nameKey, myArray) { 212 | for (var i = 0; i < myArray.length; i++) { 213 | if (myArray[i].name === nameKey) { 214 | return myArray[i]; 215 | } 216 | } 217 | } 218 | 219 | var ftpClient = new Client(); 220 | 221 | ftpClient.connect({ 222 | host: 'aebnftp.dataconversions.biz', 223 | user: conf.settings.adultempire.user, 224 | password: conf.settings.adultempire.pass 225 | }); 226 | 227 | ftpClient.on('ready', function() { 228 | 229 | /** Change directory on FTP server */ 230 | ftpClient.cwd(dstPath, function(err, currentDir) { 231 | if (err) throw err; 232 | console.log(`Directory changed to ${dstPath}`); 233 | 234 | ftpClient.list(dstPath, function(err, data) { 235 | // console.log(JSON.stringify(data, null, 2)); // Debug 236 | if (err) { 237 | console.log(err); 238 | } 239 | var obj = search(dstFile, data); 240 | console.log(obj); 241 | // console.log('File Size: ' + obj.size + ' Bytes'); 242 | // console.log(src, obj.size); 243 | 244 | if (obj) { 245 | ftpClient.end(); 246 | console.log('File already exists on destination server\'s filesystem.'); 247 | callback(null, obj); 248 | // process.exit(0); 249 | } else { 250 | 251 | // Grab from HTTP request and stream 252 | var stream = hyperquest(event.url); 253 | console.time("upload"); 254 | 255 | // Pipe stream to destination FTP server 256 | ftpClient.put(stream, dstFile, function(err) { 257 | if (err) { 258 | console.log(err); 259 | } 260 | ftpClient.end(); 261 | console.timeEnd("upload"); 262 | console.log("Finished"); 263 | }); 264 | } 265 | }); 266 | }); 267 | }); 268 | 269 | var upload = function() { 270 | ftpClient.size(dstFile, function(err, size) { 271 | // Assuming the err is the file not existing, good enough for now 272 | // err.code will give the exact status code otherwise (550 is file not found) 273 | var stream = hyperquest('event.url'); 274 | if (err) { 275 | 276 | hyperquest('event.url').pipe(res)(function(res) { 277 | // console.log(stream); 278 | ftpClient.put(stream, dstFile, function(err) { 279 | if (err) { 280 | console.log(err); 281 | } 282 | ftpClient.end(); 283 | console.timeEnd("upload"); 284 | console.log("Finished"); 285 | }); 286 | }); 287 | 288 | } else { 289 | 290 | console.log("Resuming download at start: " + size); 291 | getFileFromS3(size, function(res) { 292 | 293 | ftpClient.append(res, dstFile, function(err) { 294 | if (err) { 295 | console.log(err); 296 | } 297 | 298 | ftpClient.end(); 299 | console.timeEnd("upload"); 300 | console.log("Finished"); 301 | }); 302 | }); 303 | 304 | } 305 | }); 306 | }; 307 | 308 | ftpClient.on('close', function(hadError) { 309 | if (hadError) { 310 | console.log("FTP server closed with an error"); 311 | // callback("FTP server closed with an error"); 312 | } else { 313 | console.log("FTP server closed"); 314 | // done(); 315 | } 316 | }); 317 | 318 | ftpClient.on('error', function(err) { 319 | console.log("FTP server had error: " + err); 320 | }); 321 | 322 | 323 | ftpClient.on('end', function() { 324 | console.log("FTP server ended connection"); 325 | }); 326 | 327 | ftpClient.on('greeting', function(msg) { 328 | console.log(msg); 329 | }); 330 | 331 | } 332 | 333 | module.exports = { 334 | upload: upload, 335 | httpUpload: httpUpload 336 | }; 337 | -------------------------------------------------------------------------------- /api/routes/adultempire/index.js: -------------------------------------------------------------------------------- 1 | var adultempire = require('express').Router({ 2 | mergeParams: true 3 | }); 4 | var path = require('path'); 5 | var bodyParser = require('body-parser') 6 | var jsonParser = bodyParser.json() 7 | 8 | // clips4sale Helper 9 | const adultempireHelper = require('./adultempireHelper.js'); 10 | 11 | const conf = require(path.join(process.env.APPDATA, "clipnuke", "config.json")); 12 | 13 | adultempire.post('/', jsonParser, function(req, res) { 14 | if (!req.headers.authorization || req.headers.authorization.split(' ')[0] !== 'Bearer') { 15 | res.status(401).send('Missing Authentication Method.'); 16 | } else { 17 | var event = req.body; 18 | const credentials = { 19 | user: conf.settings.adultempire.user, 20 | pass: conf.settings.adultempire.pass 21 | }; 22 | // console.log(req, res); 23 | event.credentials = []; 24 | event.credentials.push(credentials); 25 | console.log(event); 26 | adultempireHelper.upload(req.body, function(err, data) { 27 | if (err) { 28 | callback(err, data); 29 | } else { 30 | console.log(data); 31 | res.status(200).json(data); 32 | } 33 | }); 34 | // console.log(req.body); // your JSON 35 | // res.send(req.body); // echo the result back 36 | } 37 | }); 38 | 39 | module.exports = adultempire; 40 | -------------------------------------------------------------------------------- /api/routes/aebn/aebnHelper.js: -------------------------------------------------------------------------------- 1 | var hyperquest = require('hyperquest'); 2 | var fs = require('fs'); 3 | var path = require('path'); 4 | var Client = require('ftp'); 5 | var Minio = require('minio'); 6 | 7 | function upload(event, callback) { 8 | 9 | var dstFile = path.basename(event.url); 10 | 11 | console.log('File: ', dstFile) 12 | 13 | function search(nameKey, myArray) { 14 | for (var i = 0; i < myArray.length; i++) { 15 | if (myArray[i].name === nameKey) { 16 | return myArray[i]; 17 | } 18 | } 19 | } 20 | 21 | var ftpClient = new Client(); 22 | 23 | ftpClient.connect({ 24 | host: 'aebnftp.dataconversions.biz', 25 | user: conf.settings.aebn.user, 26 | password: conf.settings.aebn.pass 27 | }); 28 | 29 | ftpClient.on('ready', function() { 30 | 31 | /* var src = request({ 32 | url: event.url, 33 | method: "HEAD" 34 | }, function(err, response, body) { 35 | console.log(response.headers); 36 | return response.headers; 37 | // process.exit(0); 38 | }); */ 39 | // console.log(size); 40 | 41 | ftpClient.list('/', function(err, data) { 42 | // console.log(JSON.stringify(data, null, 2)); // Debug 43 | if (err) { 44 | console.log(err); 45 | } 46 | var obj = search(dstFile, data); 47 | console.log(obj); 48 | // console.log('File Size: ' + obj.size + ' Bytes'); 49 | // console.log(src, obj.size); 50 | 51 | if (obj) { 52 | ftpClient.end(); 53 | console.log('File already exists on destination server\'s filesystem.'); 54 | callback(null, obj); 55 | // process.exit(0); 56 | } else { 57 | 58 | if (event.type == "video") { 59 | 60 | // Allow insecure TLS connections 61 | process.env['NODE_TLS_REJECT_UNAUTHORIZED'] = '0'; 62 | 63 | // Setup minio client 64 | var minioClient = new Minio.Client({ 65 | endPoint: conf.settings.s3.endpoint, 66 | port: conf.settings.s3.port, 67 | useSSL: true, 68 | accessKey: conf.settings.s3.access_key, 69 | secretKey: conf.settings.s3.secret_key 70 | }); 71 | 72 | var size = 0; 73 | 74 | // Grab our video file from an s3-compatible server and stream (dataStream) 75 | minioClient.getObject('vods', event.url, function(err, dataStream) { 76 | if (err) { 77 | return console.log(err) 78 | } 79 | dataStream.on('data', function(chunk) { 80 | size += chunk.length 81 | }) 82 | dataStream.on('end', function() { 83 | console.log('End. Total size = ' + size) 84 | }) 85 | dataStream.on('error', function(err) { 86 | console.log(err) 87 | }) 88 | 89 | console.time("upload"); 90 | 91 | // Pipe stream to destination FTP server 92 | ftpClient.put(dataStream, dstFile, function(err) { 93 | if (err) { 94 | console.log(err); 95 | } 96 | ftpClient.end(); 97 | console.timeEnd("upload"); 98 | console.log("Finished"); 99 | }); 100 | }); 101 | } else { 102 | 103 | // Grab from HTTP request and stream 104 | var stream = hyperquest(event.url); 105 | console.time("upload"); 106 | 107 | // Pipe stream to destination FTP server 108 | ftpClient.put(stream, dstFile, function(err) { 109 | if (err) { 110 | console.log(err); 111 | } 112 | ftpClient.end(); 113 | console.timeEnd("upload"); 114 | console.log("Finished"); 115 | }); 116 | } 117 | } 118 | }); 119 | 120 | }); 121 | 122 | var upload = function() { 123 | ftpClient.size(dstFile, function(err, size) { 124 | // Assuming the err is the file not existing, good enough for now 125 | // err.code will give the exact status code otherwise (550 is file not found) 126 | var stream = hyperquest('event.url'); 127 | if (err) { 128 | 129 | hyperquest('event.url').pipe(res)(function(res) { 130 | // console.log(stream); 131 | ftpClient.put(stream, dstFile, function(err) { 132 | if (err) { 133 | console.log(err); 134 | } 135 | ftpClient.end(); 136 | console.timeEnd("upload"); 137 | console.log("Finished"); 138 | }); 139 | }); 140 | 141 | } else { 142 | 143 | console.log("Resuming download at start: " + size); 144 | getFileFromS3(size, function(res) { 145 | 146 | ftpClient.append(res, dstFile, function(err) { 147 | if (err) { 148 | console.log(err); 149 | } 150 | 151 | ftpClient.end(); 152 | console.timeEnd("upload"); 153 | console.log("Finished"); 154 | }); 155 | }); 156 | 157 | } 158 | }); 159 | }; 160 | 161 | ftpClient.on('close', function(hadError) { 162 | if (hadError) { 163 | console.log("FTP server closed with an error"); 164 | // callback("FTP server closed with an error"); 165 | } else { 166 | console.log("FTP server closed"); 167 | // done(); 168 | } 169 | }); 170 | 171 | ftpClient.on('error', function(err) { 172 | console.log("FTP server had error: " + err); 173 | }); 174 | 175 | 176 | ftpClient.on('end', function() { 177 | console.log("FTP server ended connection"); 178 | }); 179 | 180 | ftpClient.on('greeting', function(msg) { 181 | console.log(msg); 182 | }); 183 | 184 | } 185 | 186 | function httpUpload(event, callback) { 187 | 188 | var dstFile = path.basename(event.url); 189 | var ext = path.extname(event.url); 190 | var dstPath; 191 | if (ext == ".mp4" || ".wmv" || ".mov" || ".avi") { 192 | dstPath = '/clips'; 193 | } else if (ext == ".jpg" || ".gif" || ".png" || ".jpeg" || ".tiff" || ".tif") { 194 | dstPath = '/clip_images'; 195 | } 196 | switch (event.type) { 197 | case "trailer": 198 | dstPath = '/clips_previews'; 199 | break; 200 | case "video": 201 | dstPath = '/clips'; 202 | break; 203 | case "poster": 204 | dstPath = '/clip_images'; 205 | break; 206 | } 207 | console.log('File: ', dstFile) 208 | 209 | function search(nameKey, myArray) { 210 | for (var i = 0; i < myArray.length; i++) { 211 | if (myArray[i].name === nameKey) { 212 | return myArray[i]; 213 | } 214 | } 215 | } 216 | 217 | var ftpClient = new Client(); 218 | 219 | ftpClient.connect({ 220 | host: 'aebnftp.dataconversions.biz', 221 | user: conf.settings.aebn.user, 222 | password: conf.settings.aebn.pass 223 | }); 224 | 225 | ftpClient.on('ready', function() { 226 | 227 | /** Change directory on FTP server */ 228 | ftpClient.cwd(dstPath, function(err, currentDir) { 229 | if (err) throw err; 230 | console.log(`Directory changed to ${dstPath}`); 231 | 232 | ftpClient.list(dstPath, function(err, data) { 233 | // console.log(JSON.stringify(data, null, 2)); // Debug 234 | if (err) { 235 | console.log(err); 236 | } 237 | var obj = search(dstFile, data); 238 | console.log(obj); 239 | // console.log('File Size: ' + obj.size + ' Bytes'); 240 | // console.log(src, obj.size); 241 | 242 | if (obj) { 243 | ftpClient.end(); 244 | console.log('File already exists on destination server\'s filesystem.'); 245 | callback(null, obj); 246 | // process.exit(0); 247 | } else { 248 | 249 | // Grab from HTTP request and stream 250 | var stream = hyperquest(event.url); 251 | console.time("upload"); 252 | 253 | // Pipe stream to destination FTP server 254 | ftpClient.put(stream, dstFile, function(err) { 255 | if (err) { 256 | console.log(err); 257 | } 258 | ftpClient.end(); 259 | console.timeEnd("upload"); 260 | console.log("Finished"); 261 | }); 262 | } 263 | }); 264 | }); 265 | }); 266 | 267 | var upload = function() { 268 | ftpClient.size(dstFile, function(err, size) { 269 | // Assuming the err is the file not existing, good enough for now 270 | // err.code will give the exact status code otherwise (550 is file not found) 271 | var stream = hyperquest('event.url'); 272 | if (err) { 273 | 274 | hyperquest('event.url').pipe(res)(function(res) { 275 | // console.log(stream); 276 | ftpClient.put(stream, dstFile, function(err) { 277 | if (err) { 278 | console.log(err); 279 | } 280 | ftpClient.end(); 281 | console.timeEnd("upload"); 282 | console.log("Finished"); 283 | }); 284 | }); 285 | 286 | } else { 287 | 288 | console.log("Resuming download at start: " + size); 289 | getFileFromS3(size, function(res) { 290 | 291 | ftpClient.append(res, dstFile, function(err) { 292 | if (err) { 293 | console.log(err); 294 | } 295 | 296 | ftpClient.end(); 297 | console.timeEnd("upload"); 298 | console.log("Finished"); 299 | }); 300 | }); 301 | 302 | } 303 | }); 304 | }; 305 | 306 | ftpClient.on('close', function(hadError) { 307 | if (hadError) { 308 | console.log("FTP server closed with an error"); 309 | // callback("FTP server closed with an error"); 310 | } else { 311 | console.log("FTP server closed"); 312 | // done(); 313 | } 314 | }); 315 | 316 | ftpClient.on('error', function(err) { 317 | console.log("FTP server had error: " + err); 318 | }); 319 | 320 | 321 | ftpClient.on('end', function() { 322 | console.log("FTP server ended connection"); 323 | }); 324 | 325 | ftpClient.on('greeting', function(msg) { 326 | console.log(msg); 327 | }); 328 | 329 | } 330 | 331 | function localUpload(event, callback) { 332 | console.log(event.url); 333 | 334 | var dstFile = path.basename(event.url); 335 | var ext = path.extname(event.url); 336 | var dstPath; 337 | if (ext == ".mp4" || ".wmv" || ".mov" || ".avi") { 338 | dstPath = '/clips'; 339 | } else if (ext == ".jpg" || ".gif" || ".png" || ".jpeg" || ".tiff" || ".tif") { 340 | dstPath = '/clip_images'; 341 | } 342 | switch (event.type) { 343 | case "trailer": 344 | dstPath = '/clips_previews'; 345 | break; 346 | case "video": 347 | dstPath = '/clips'; 348 | break; 349 | case "poster": 350 | dstPath = '/clip_images'; 351 | break; 352 | } 353 | console.log('File: ', dstFile) 354 | 355 | function search(nameKey, myArray) { 356 | for (var i = 0; i < myArray.length; i++) { 357 | if (myArray[i].name === nameKey) { 358 | return myArray[i]; 359 | } 360 | } 361 | } 362 | 363 | var ftpClient = new Client(); 364 | 365 | ftpClient.connect({ 366 | host: 'aebnftp.dataconversions.biz', 367 | user: event["credentials"][0]["user"] || process.env.AEBN_USER, 368 | password: event["credentials"][0]["pass"] || process.env.AEBN_PASS 369 | }); 370 | 371 | ftpClient.on('ready', function() { 372 | // Pipe stream to destination FTP server 373 | ftpClient.put("X:\\S3Gateway\\NeroMedia\\xxxmultimedia-downloads\\" + event.url, dstFile, function(err) { 374 | console.time("upload"); 375 | if (err) { 376 | console.log(err); 377 | } 378 | ftpClient.end(); 379 | console.timeEnd("upload"); 380 | console.log("Finished"); 381 | }); 382 | /** Change directory on FTP server */ 383 | // ftpClient.cwd(dstPath, function(err, currentDir) { 384 | // if (err) throw err; 385 | // console.log(`Directory changed to ${dstPath}`); 386 | 387 | // ftpClient.list("/", function(err, data) { 388 | // // console.log(JSON.stringify(data, null, 2)); // Debug 389 | // if (err) {console.log(err);} 390 | // var obj = search(dstFile, data); 391 | // console.log(obj); 392 | // // console.log('File Size: ' + obj.size + ' Bytes'); 393 | // // console.log(src, obj.size); 394 | // 395 | // if (obj) { 396 | // ftpClient.end(); 397 | // console.log('File already exists on destination server\'s filesystem.'); 398 | // callback(null, obj); 399 | // // process.exit(0); 400 | // } else { 401 | // 402 | // // Grab from HTTP request and stream 403 | // // var stream = hyperquest(event.url); 404 | // console.time("upload"); 405 | // 406 | // // Pipe stream to destination FTP server 407 | // ftpClient.put(event.url, dstFile, function(err) { 408 | // if (err) { console.log(err); } 409 | // ftpClient.end(); 410 | // console.timeEnd("upload"); 411 | // console.log("Finished"); 412 | // }); 413 | // } 414 | // }); 415 | // }); 416 | }); 417 | 418 | var upload = function() { 419 | ftpClient.size(dstFile, function(err, size) { 420 | // Assuming the err is the file not existing, good enough for now 421 | // err.code will give the exact status code otherwise (550 is file not found) 422 | var stream = hyperquest('event.url'); 423 | if (err) { 424 | 425 | hyperquest('event.url').pipe(res)(function(res) { 426 | // console.log(stream); 427 | ftpClient.put(stream, dstFile, function(err) { 428 | if (err) { 429 | console.log(err); 430 | } 431 | ftpClient.end(); 432 | console.timeEnd("upload"); 433 | console.log("Finished"); 434 | }); 435 | }); 436 | 437 | } else { 438 | 439 | console.log("Resuming download at start: " + size); 440 | getFileFromS3(size, function(res) { 441 | 442 | ftpClient.append(res, dstFile, function(err) { 443 | if (err) { 444 | console.log(err); 445 | } 446 | 447 | ftpClient.end(); 448 | console.timeEnd("upload"); 449 | console.log("Finished"); 450 | }); 451 | }); 452 | 453 | } 454 | }); 455 | }; 456 | 457 | ftpClient.on('close', function(hadError) { 458 | if (hadError) { 459 | console.log("FTP server closed with an error"); 460 | // callback("FTP server closed with an error"); 461 | } else { 462 | console.log("FTP server closed"); 463 | // done(); 464 | } 465 | }); 466 | 467 | ftpClient.on('error', function(err) { 468 | console.log("FTP server had error: " + err); 469 | }); 470 | 471 | 472 | ftpClient.on('end', function() { 473 | console.log("FTP server ended connection"); 474 | }); 475 | 476 | ftpClient.on('greeting', function(msg) { 477 | console.log(msg); 478 | }); 479 | 480 | } 481 | 482 | module.exports = { 483 | upload: upload, 484 | httpUpload: httpUpload, 485 | localUpload: localUpload 486 | }; 487 | -------------------------------------------------------------------------------- /api/routes/aebn/index.js: -------------------------------------------------------------------------------- 1 | var aebn = require('express').Router({ 2 | mergeParams: true 3 | }); 4 | var path = require('path'); 5 | var bodyParser = require('body-parser') 6 | var jsonParser = bodyParser.json() 7 | 8 | // clips4sale Helper 9 | const aebnHelper = require('./aebnHelper.js'); 10 | 11 | const conf = require(path.join(process.env.APPDATA, "clipnuke", "config.json")); 12 | 13 | aebn.post('/', jsonParser, function(req, res) { 14 | var event = req.body; 15 | const credentials = { 16 | user: conf.settings.aebn.user, 17 | pass: conf.settings.aebn.pass 18 | }; 19 | // console.log(req, res); 20 | event.credentials = []; 21 | event.credentials.push(credentials); 22 | console.log(event); 23 | aebnHelper.localUpload(req.body, function(err, data) { 24 | if (err) { 25 | callback(err, data); 26 | } else { 27 | console.log(data); 28 | res.status(200).json(data); 29 | } 30 | }); 31 | // console.log(req.body); // your JSON 32 | // res.send(req.body); // echo the result back 33 | }); 34 | 35 | module.exports = aebn; 36 | -------------------------------------------------------------------------------- /api/routes/azure/azureHelper.js: -------------------------------------------------------------------------------- 1 | function translate(event, apiKey, callback) { 2 | console.log(event); 3 | const request = require('request'); 4 | const uuidv4 = require('uuid/v4'); 5 | /* Checks to see if the subscription key is available 6 | as an environment variable. If you are setting your subscription key as a 7 | string, then comment these lines out. 8 | 9 | If you want to set your subscription key as a string, replace the value for 10 | the Ocp-Apim-Subscription-Key header as a string. */ 11 | const subscriptionKey = apiKey; 12 | if (!subscriptionKey) { 13 | throw new Error('Environment variable for your subscription key is not set.') 14 | }; 15 | let options = { 16 | method: 'POST', 17 | baseUrl: 'https://api.cognitive.microsofttranslator.com/', 18 | url: 'translate', 19 | qs: { 20 | 'api-version': '3.0', 21 | 'to': event.lang 22 | }, 23 | headers: { 24 | 'Ocp-Apim-Subscription-Key': subscriptionKey, 25 | 'Content-type': 'application/json', 26 | 'X-ClientTraceId': uuidv4().toString() 27 | }, 28 | body: [{ 29 | 'text': event.text 30 | }], 31 | json: true, 32 | }; 33 | request(options, function(err, res, body) { 34 | if (err) { 35 | console.log(err); 36 | callback(err, err.msg); 37 | } else { 38 | console.log(JSON.stringify(body, null, 4)); 39 | callback(null, body); 40 | } 41 | }); 42 | }; 43 | 44 | module.exports = { 45 | translate: translate, 46 | }; 47 | -------------------------------------------------------------------------------- /api/routes/azure/index.js: -------------------------------------------------------------------------------- 1 | var azure = require('express').Router({ 2 | mergeParams: true 3 | }); 4 | const path = require('path'); 5 | var bodyParser = require('body-parser') 6 | var jsonParser = bodyParser.json() 7 | 8 | // Helper 9 | const azureHelper = require('./azureHelper.js'); 10 | 11 | const conf = require(path.join(process.env.APPDATA, "clipnuke", "config.json")); 12 | 13 | // API Key - Pre-authenticated 14 | const apiKey = conf.settings.azure.api_key || ""; 15 | 16 | // Test Route 17 | azure.get('/', (req, res) => { 18 | res.status(200).json({ 19 | message: 'Azure Router!' 20 | }); 21 | }); 22 | 23 | // route to trigger the capture 24 | azure.post('/translate', jsonParser, function(req, res) { 25 | var event = req.body; 26 | console.log(event); 27 | azureHelper.translate(event, apiKey, function(err, data) { 28 | if (err) { 29 | res.status(500).send(err); 30 | } else { 31 | console.log(data); 32 | res.json(data); 33 | } 34 | }); 35 | }); 36 | 37 | module.exports = azure; 38 | -------------------------------------------------------------------------------- /api/routes/clipnuke/cnHelper.js: -------------------------------------------------------------------------------- 1 | var hyperquest = require('hyperquest'); 2 | var fs = require('fs'); 3 | var path = require('path'); 4 | const conf = require(path.join(process.env.APPDATA, "clipnuke", "config.json")); 5 | var Client = require('ftp'); 6 | var Minio = require('minio'); 7 | 8 | // Allow insecure TLS connections 9 | process.env['NODE_TLS_REJECT_UNAUTHORIZED'] = '0'; 10 | 11 | // Make sure user has filled out necessary info. 12 | if (conf.settings.s3.endpoint && conf.settings.s3.access_key && conf.settings.s3.secret_key) { 13 | // Setup minio client 14 | var minioClient = new Minio.Client({ 15 | endPoint: conf.settings.s3.endpoint, 16 | port: conf.settings.s3.port || 9000, 17 | useSSL: conf.settings.s3.use_ssl || true, 18 | accessKey: conf.settings.s3.access_key, 19 | secretKey: conf.settings.s3.secret_key 20 | }); 21 | } 22 | 23 | function getTrailerObjectKeys(params, callback) { 24 | var data = {}; 25 | var size = 0; 26 | var bucketName = params.bucketName || 'clipnuke'; 27 | data.objects = []; 28 | data.objects.push({ 29 | name: "Select a File" 30 | }); 31 | 32 | // Grab our video file from an s3-compatible server and stream (dataStream) 33 | /* minioClient.listObjects(bucketName, '', true, function(err, data) { 34 | if (err) { 35 | return console.log(err) 36 | } 37 | callback(null, data) 38 | }, 3000); */ 39 | 40 | var stream = minioClient.listObjects(bucketName, 'trailers/', true) 41 | stream.on('data', function(obj) { 42 | data.objects.push(obj); 43 | console.log(obj) 44 | }); 45 | 46 | stream.on('error', function(err) { 47 | console.log(err) 48 | callback(err, data); 49 | }); 50 | 51 | stream.on('end', function(err) { 52 | console.log(err) 53 | callback(null, data); 54 | }); 55 | } 56 | 57 | function getVideoObjectKeys(params, callback) { 58 | var data = {}; 59 | var size = 0; 60 | var bucketName = params.bucketName || 'xxxmultimedia-downloads'; 61 | data.objects = []; 62 | data.objects.push({ 63 | name: "Select a File" 64 | }); 65 | 66 | // Grab our video file from an s3-compatible server and stream (dataStream) 67 | /* minioClient.listObjects(bucketName, '', true, function(err, data) { 68 | if (err) { 69 | return console.log(err) 70 | } 71 | callback(null, data) 72 | }, 3000); */ 73 | 74 | var stream = minioClient.listObjects(bucketName, '', true) 75 | stream.on('data', function(obj) { 76 | data.objects.push(obj); 77 | console.log(obj) 78 | }); 79 | 80 | stream.on('error', function(err) { 81 | console.log(err) 82 | callback(err, data); 83 | }); 84 | 85 | stream.on('end', function(err) { 86 | console.log(err) 87 | callback(null, data); 88 | }); 89 | } 90 | 91 | function getVodObjectKeys(params, callback) { 92 | var data = {}; 93 | var size = 0; 94 | var bucketName = 'vods'; 95 | data.objects = []; 96 | data.objects.push({ 97 | name: "Select a File" 98 | }); 99 | 100 | // Grab our video file from an s3-compatible server and stream (dataStream) 101 | /* minioClient.listObjects(bucketName, '', true, function(err, data) { 102 | if (err) { 103 | return console.log(err) 104 | } 105 | callback(null, data) 106 | }, 3000); */ 107 | 108 | var stream = minioClient.listObjects(bucketName, '', true) 109 | stream.on('data', function(obj) { 110 | data.objects.push(obj); 111 | console.log(obj) 112 | }); 113 | 114 | stream.on('error', function(err) { 115 | console.log(err) 116 | callback(err, data); 117 | }); 118 | 119 | stream.on('end', function(err) { 120 | console.log(err) 121 | callback(null, data); 122 | }); 123 | } 124 | 125 | module.exports = { 126 | getTrailerObjectKeys: getTrailerObjectKeys, 127 | getVideoObjectKeys: getVideoObjectKeys, 128 | getVodObjectKeys 129 | }; 130 | -------------------------------------------------------------------------------- /api/routes/clipnuke/index.js: -------------------------------------------------------------------------------- 1 | var clipnuke = require('express').Router({ 2 | mergeParams: true 3 | }); 4 | var bodyParser = require('body-parser') 5 | var cookieParser = require('cookie-parser') 6 | var bearerToken = require('express-bearer-token') 7 | var jsonParser = bodyParser.json() 8 | // var influx = require('./influx'); 9 | var upload = require('./upload'); 10 | 11 | // clipnuke Helper 12 | const cn = require('./cnHelper.js'); 13 | 14 | // Middleware 15 | clipnuke.use(cookieParser()) 16 | clipnuke.use(bearerToken()); 17 | 18 | // Test Route 19 | clipnuke.get('/', (req, res) => { 20 | res.status(200).json({ 21 | message: 'clipnuke Router!' 22 | }); 23 | }); 24 | 25 | clipnuke.get('/trailers', function(req, res) { 26 | var event = req.body; 27 | // res.json({id}); 28 | 29 | const params = { 30 | // accessKey: event.accessKey, 31 | // secretKey: event.secretKey 32 | }; 33 | 34 | cn.getTrailerObjectKeys(params, function(err, data) { 35 | console.log(data); 36 | res.json(data); 37 | }); 38 | 39 | }); 40 | 41 | clipnuke.get('/videos', function(req, res) { 42 | var event = req.body; 43 | // res.json({id}); 44 | 45 | const params = { 46 | // accessKey: event.accessKey, 47 | // secretKey: event.secretKey 48 | }; 49 | 50 | cn.getVideoObjectKeys(params, function(err, data) { 51 | console.log(data); 52 | res.json(data); 53 | }); 54 | 55 | }); 56 | 57 | clipnuke.get('/vods', function(req, res) { 58 | var event = req.body; 59 | // res.json({id}); 60 | 61 | const params = { 62 | // accessKey: event.accessKey, 63 | // secretKey: event.secretKey 64 | }; 65 | 66 | cn.getVodObjectKeys(params, function(err, data) { 67 | console.log(data); 68 | res.json(data); 69 | }); 70 | 71 | }); 72 | 73 | clipnuke.get('/buckets', function(req, res) { 74 | var event = req.body; 75 | console.log('Cookies: ', req.cookies) 76 | 77 | // res.json({id}); 78 | 79 | const params = { 80 | // accessKey: event.accessKey, 81 | // secretKey: event.secretKey 82 | }; 83 | 84 | cn.getBuckets(params, function(err, data) { 85 | console.log(data); 86 | res.json(data); 87 | }); 88 | 89 | }); 90 | 91 | clipnuke.get('/test', function(req, res) { 92 | var event = req.body; 93 | console.log('Cookies: ', req.cookies) 94 | console.log('Token: ', req.token) 95 | 96 | res.send('Token ' + req.token); 97 | 98 | }); 99 | 100 | /** 101 | * clipnuke Router 102 | * @type {String} 103 | */ 104 | // clipnuke.use('/sales', sales); 105 | 106 | // clipnuke.use('/influx', influx); 107 | clipnuke.use('/upload', upload); 108 | 109 | module.exports = clipnuke; 110 | -------------------------------------------------------------------------------- /api/routes/clipnuke/upload/index.js: -------------------------------------------------------------------------------- 1 | var upload = require('express').Router({ 2 | mergeParams: true 3 | }); 4 | var bodyParser = require('body-parser') 5 | var jsonParser = bodyParser.json() 6 | 7 | // upload Helper 8 | const uploadHelper = require('./uploadHelper.js'); 9 | 10 | // Test Route 11 | upload.get('/', (req, res) => { 12 | res.status(200).json({ 13 | message: 'upload Router!' 14 | }); 15 | }); 16 | 17 | upload.post('/trailers', function(req, res) { 18 | var event = req.body; 19 | // res.json({id}); 20 | 21 | const params = { 22 | // accessKey: event.accessKey, 23 | // secretKey: event.secretKey 24 | }; 25 | 26 | cn.getTrailerObjectKeys(params, function(err, data) { 27 | console.log(data); 28 | res.json(data); 29 | }); 30 | 31 | }); 32 | 33 | upload.post('/videos', function(req, res) { 34 | var event = req.body; 35 | // res.json({id}); 36 | 37 | const params = { 38 | // accessKey: event.accessKey, 39 | // secretKey: event.secretKey 40 | }; 41 | 42 | cn.getVideoObjectKeys(params, function(err, data) { 43 | console.log(data); 44 | res.json(data); 45 | }); 46 | 47 | }); 48 | 49 | upload.post('/thumbnails', function(req, res) { 50 | var event = req.body; 51 | console.log('Cookies: ', req.cookies) 52 | 53 | // res.json({id}); 54 | 55 | const params = { 56 | // accessKey: event.accessKey, 57 | // secretKey: event.secretKey 58 | }; 59 | 60 | cn.getBuckets(params, function(err, data) { 61 | console.log(data); 62 | res.json(data); 63 | }); 64 | 65 | }); 66 | 67 | /** 68 | * upload Router 69 | * @type {String} 70 | */ 71 | // upload.use('/sales', sales); 72 | 73 | // upload.use('/influx', influx); 74 | 75 | module.exports = upload; 76 | -------------------------------------------------------------------------------- /api/routes/clipnuke/upload/uploadHelper.js: -------------------------------------------------------------------------------- 1 | var hyperquest = require('hyperquest'); 2 | var fs = require('fs'); 3 | var path = require('path'); 4 | var Client = require('ftp'); 5 | var Minio = require('minio'); 6 | 7 | // Allow insecure TLS connections 8 | process.env['NODE_TLS_REJECT_UNAUTHORIZED'] = '0'; 9 | 10 | const conf = require(path.join(process.env.APPDATA, "clipnuke", "config.json")); 11 | 12 | if (conf.settings.s3.endpoint && conf.settings.s3.access_key && conf.settings.s3.secret_key) { 13 | // Setup minio client 14 | var minioClient = new Minio.Client({ 15 | endPoint: conf.settings.s3.endpoint, 16 | port: conf.settings.s3.port || 9000, 17 | useSSL: conf.settings.s3.use_ssl || true, 18 | accessKey: conf.settings.s3.access_key, 19 | secretKey: conf.settings.s3.secret_key 20 | }); 21 | } 22 | 23 | function getTrailerObjectKeys(params, callback) { 24 | var data = {}; 25 | var size = 0; 26 | var bucketName = conf.settings.s3.bucket_name; 27 | data.objects = []; 28 | data.objects.push({ 29 | name: "Select a File" 30 | }); 31 | 32 | // Grab our video file from an s3-compatible server and stream (dataStream) 33 | /* minioClient.listObjects(bucketName, '', true, function(err, data) { 34 | if (err) { 35 | return console.log(err) 36 | } 37 | callback(null, data) 38 | }, 3000); */ 39 | 40 | var stream = minioClient.listObjects(bucketName, 'trailers/', true) 41 | stream.on('data', function(obj) { 42 | data.objects.push(obj); 43 | console.log(obj) 44 | }); 45 | 46 | stream.on('error', function(err) { 47 | console.log(err) 48 | callback(err, data); 49 | }); 50 | 51 | stream.on('end', function(err) { 52 | console.log(err) 53 | callback(null, data); 54 | }); 55 | } 56 | 57 | function getVideoObjectKeys(params, callback) { 58 | var data = {}; 59 | var size = 0; 60 | var bucketName = conf.settings.s3.bucket_name; 61 | data.objects = []; 62 | data.objects.push({ 63 | name: "Select a File" 64 | }); 65 | 66 | // Grab our video file from an s3-compatible server and stream (dataStream) 67 | /* minioClient.listObjects(bucketName, '', true, function(err, data) { 68 | if (err) { 69 | return console.log(err) 70 | } 71 | callback(null, data) 72 | }, 3000); */ 73 | 74 | var stream = minioClient.listObjects(bucketName, '', true) 75 | stream.on('data', function(obj) { 76 | data.objects.push(obj); 77 | console.log(obj) 78 | }); 79 | 80 | stream.on('error', function(err) { 81 | console.log(err) 82 | callback(err, data); 83 | }); 84 | 85 | stream.on('end', function(err) { 86 | console.log(err) 87 | callback(null, data); 88 | }); 89 | } 90 | 91 | module.exports = { 92 | getTrailerObjectKeys: getTrailerObjectKeys, 93 | getVideoObjectKeys: getVideoObjectKeys 94 | }; 95 | -------------------------------------------------------------------------------- /api/routes/clips4sale/c4sHelper.js: -------------------------------------------------------------------------------- 1 | const dateutil = require('dateutil'); 2 | const dateFormat = require('dateformat'); 3 | var HashMap = require('hashmap'); 4 | var fs = require('fs'); 5 | var path = require('path'); 6 | 7 | // Create accociative array for the clip title suffix 8 | var map = new HashMap(); 9 | map 10 | .set("HD_MP4", " - Full HD 1080p MP4") 11 | .set("SD_MP4", " - SD 480p MP4") 12 | .set("HD_WMV", " - Full HD 1080p WMV") 13 | .set("SD_WMV", " - SD 480p WMV") 14 | .set("MOBILE_HD", " - Mobile hd 720p MP4") 15 | .set("MOBILE_LOW", " - Mobile Low MP4"); 16 | 17 | /** 18 | * Login to Clips4Sale. 19 | * Init a new webdriverio session. 20 | * @param {webdriverio} client A webdriverio client 21 | * @param {Function} callback err, data 22 | * @return {Object} A webdriverio cookie containing the authenticated PHPSESSID 23 | */ 24 | function auth(credentials, params, callback) { 25 | console.log(credentials); 26 | console.log("Session ID: ", params.client.sessionId) 27 | // TODO Get fresh session if sessionId is defined 28 | if (params.client.sessionId) { 29 | params.client.end(); 30 | } 31 | // console.log(params.client); 32 | params.client 33 | .init().catch(function(err) { 34 | params.client.end(); 35 | console.log('WDIO.init() failed.', params); 36 | return callback(`WDIO.init() failed.`, {}); 37 | }, params) 38 | .url('https://admin.clips4sale.com/login/index') 39 | .waitForVisible('input#username', 3000) 40 | .setValue('input#username', credentials.user) 41 | .setValue('input#password', credentials.pass).pause(200) 42 | // .submitForm('input.btn-primary') 43 | .click('input.btn.btn-primary') 44 | .setCookie({ 45 | domain: "admin.clips4sale.com", 46 | name: "PHPSESSID", 47 | secure: false, 48 | value: credentials.phpsessid, 49 | // expiry: seconds+3600 // When the cookie expires, specified in seconds since Unix Epoch 50 | }) 51 | // .pause(15000) // Wait in case we need to solve a recaptcha. 52 | /* .getCookie([{"domain":"admin.clips4sale.com","httpOnly":false,"name":"PHPSESSID","path":"/","secure":false,"value":"jt0p2kiigvqdps9paqn6nqpnm8"}]).then(function(cookie) { 53 | var json = JSON.stringify(cookie); 54 | console.log('Cookie is: ' + json); 55 | fs.writeFile('cookie.json', json, 'utf8', callback); 56 | return cookie; 57 | }) */ 58 | .next(function(data) { 59 | console.log(data); 60 | return callback(null, data); 61 | }).catch((e) => console.log(e)); 62 | }; 63 | 64 | /** 65 | * Edit Vid - Details 66 | * Sends a GET request to the server, using an authenticated webdriverio session, fetches the data, then ends the session. 67 | * NOTE: It's super important to use .end() method to end the browser session. Because {@link auth | auth} calls init() to open a new browser session. 68 | * IMPORTANT: If we don't run browser.end(), this app will fail when {@link getVid | getVid} or another method is called! 69 | * @param {Integer} id A ManyVids Video ID 70 | * @param {Object} params client, cookie 71 | * @param {Function} callback [description] 72 | * @return {Object} An object containing details about a ManyVids video. 73 | */ 74 | function getClip(id, params, callback) { 75 | var data = {}; 76 | var dateObj = {}; 77 | var formData = {}; 78 | formData.relatedCategories = []; 79 | formData.tags = []; 80 | formData.website = "CLIPS4SALE"; 81 | formData.remoteId = id * 1; 82 | 83 | params.client 84 | // .setCookie(params.cookie) 85 | .url(`https://admin.clips4sale.com/clips/show/${id}`) 86 | .waitForVisible('input[name="ClipTitle"]', 90000) 87 | .execute(function(data) { 88 | // Convert the raw HTML from tinyMCE into a JSON friendly version with himalaya 89 | data.description = tinyMCE.activeEditor.getContent({ 90 | format: "raw" 91 | }); 92 | // data.description = tinyMCE.activeEditor.getContent({format: "raw"}); 93 | return data.description; 94 | }, data).then(function(data) { 95 | // Convert the raw HTML from tinyMCE into a JSON friendly version with himalaya 96 | // Then we need to stringify for Graph.cool to escape the quotes 97 | /** @todo UPDATE: Okay so apparently JSON.stringify() causes problems when updating a record in Graphcool. So... */ 98 | // formData.description = himalaya.parse(data.value); 99 | formData.description = data.value; 100 | // formData.description = JSON.stringify(himalaya.parse(data.value)); 101 | }) 102 | .getValue('input[name="ClipTitle"]').then(function(val) { 103 | console.log('Title is: ' + JSON.stringify(val)); 104 | formData.name = val; 105 | }) 106 | .getValue('input[name="producer_id"]').then(function(val) { 107 | // console.log('Studio ID is: ' + JSON.stringify(val)); 108 | formData.remoteStudioId = val * 1; 109 | }) 110 | .execute(function(data) { 111 | data.price = document.frm_upload.clip_price.value; 112 | return data.price; 113 | }, data).then(function(data) { 114 | formData.price = data.value * 1; 115 | // console.log(formData.price); 116 | }) 117 | .getAttribute('#select2-keycat-container', 'title').then(function(val) { 118 | // console.log('category is: ' + JSON.stringify(val)); 119 | formData.category = val; 120 | }) 121 | .getAttribute('#select2-key1-container', 'title').then(function(val) { 122 | // console.log('key1 is: ' + JSON.stringify(val)); 123 | if (val !== null && val !== '' && val !== 'Select Related Categories') { 124 | formData.relatedCategories.push(val); 125 | } 126 | }) 127 | .getAttribute('#select2-key2-container', 'title').then(function(val) { 128 | // console.log('key2 is: ' + JSON.stringify(val)); 129 | if (val !== null && val !== '' && val !== 'Select Related Categories') { 130 | formData.relatedCategories.push(val); 131 | } 132 | }) 133 | .getAttribute('#select2-key3-container', 'title').then(function(val) { 134 | // console.log('key3 is: ' + JSON.stringify(val)); 135 | if (val !== null && val !== '' && val !== 'Select Related Categories') { 136 | formData.relatedCategories.push(val); 137 | } 138 | }) 139 | .getAttribute('#select2-key4-container', 'title').then(function(val) { 140 | // console.log('key4 is: ' + JSON.stringify(val)); 141 | if (val !== null && val !== '' && val !== 'Select Related Categories') { 142 | formData.relatedCategories.push(val); 143 | } 144 | }) 145 | .getAttribute('#select2-key5-container', 'title').then(function(val) { 146 | // console.log('key5 is: ' + JSON.stringify(val)); 147 | if (val !== null && val !== '' && val !== 'Select Related Categories') { 148 | formData.relatedCategories.push(val); 149 | } 150 | }) 151 | .getValue('input[name="keytype[0]"]').then(function(val) { 152 | // console.log('Keyword is: ' + JSON.stringify(val)); 153 | if (val !== null && val !== '') { 154 | formData.tags.push(val); 155 | } 156 | }) 157 | .getValue('input[name="keytype[1]"]').then(function(val) { 158 | // console.log('Keyword is: ' + JSON.stringify(val)); 159 | if (val !== null && val !== '') { 160 | formData.tags.push(val); 161 | } 162 | }) 163 | .getValue('input[name="keytype[2]"]').then(function(val) { 164 | // console.log('Keyword is: ' + JSON.stringify(val)); 165 | if (val !== null && val !== '') { 166 | formData.tags.push(val); 167 | } 168 | }) 169 | .getValue('input[name="keytype[3]"]').then(function(val) { 170 | // console.log('Keyword is: ' + JSON.stringify(val)); 171 | if (val !== null && val !== '') { 172 | formData.tags.push(val); 173 | } 174 | }) 175 | .getValue('input[name="keytype[4]"]').then(function(val) { 176 | // console.log('Keyword is: ' + JSON.stringify(val)); 177 | if (val !== null && val !== '') { 178 | formData.tags.push(val); 179 | } 180 | }) 181 | .getValue('input[name="keytype[5]"]').then(function(val) { 182 | // console.log('Keyword is: ' + JSON.stringify(val)); 183 | if (val !== null && val !== '') { 184 | formData.tags.push(val); 185 | } 186 | }) 187 | .getValue('input[name="keytype[6]"]').then(function(val) { 188 | // console.log('Keyword is: ' + JSON.stringify(val)); 189 | if (val !== null && val !== '') { 190 | formData.tags.push(val); 191 | } 192 | }) 193 | .getValue('input[name="keytype[7]"]').then(function(val) { 194 | // console.log('Keyword is: ' + JSON.stringify(val)); 195 | if (val !== null && val !== '') { 196 | formData.tags.push(val); 197 | } 198 | }) 199 | .getValue('input[name="keytype[8]"]').then(function(val) { 200 | // console.log('Keyword is: ' + JSON.stringify(val)); 201 | if (val !== null && val !== '') { 202 | formData.tags.push(val); 203 | } 204 | }) 205 | .getValue('input[name="keytype[9]"]').then(function(val) { 206 | // console.log('Keyword is: ' + JSON.stringify(val)); 207 | if (val !== null && val !== '') { 208 | formData.tags.push(val); 209 | } 210 | }) 211 | .getValue('input[name="keytype[10]"]').then(function(val) { 212 | // console.log('Keyword is: ' + JSON.stringify(val)); 213 | if (val !== null && val !== '') { 214 | formData.tags.push(val); 215 | } 216 | }) 217 | .getValue('input[name="keytype[11]"]').then(function(val) { 218 | // console.log('Keyword is: ' + JSON.stringify(val)); 219 | if (val !== null && val !== '') { 220 | formData.tags.push(val); 221 | } 222 | }) 223 | .getValue('input[name="keytype[12]"]').then(function(val) { 224 | // console.log('Keyword is: ' + JSON.stringify(val)); 225 | if (val !== null && val !== '') { 226 | formData.tags.push(val); 227 | } 228 | }) 229 | .getValue('input[name="keytype[13]"]').then(function(val) { 230 | // console.log('Keyword is: ' + JSON.stringify(val)); 231 | if (val !== null && val !== '') { 232 | formData.tags.push(val); 233 | } 234 | }) 235 | .getValue('input[name="keytype[14]"]').then(function(val) { 236 | // console.log('Keyword is: ' + JSON.stringify(val)); 237 | if (val !== null && val !== '') { 238 | formData.tags.push(val); 239 | } 240 | }) 241 | .getValue('input[name="DisplayOrder"]').then(function(val) { 242 | // console.log('DisplayOrder is: ' + JSON.stringify(val*1)); 243 | formData.displayOrder = val * 1; 244 | }) 245 | .getValue('input[name="ClipName"]').then(function(val) { 246 | formData.filename = val; 247 | }) 248 | .execute(function(data) { 249 | data.thumbnailFilename = $('#imageListDiv > select > option:selected')[0].value; 250 | return data.thumbnailFilename; 251 | }, data).then(function(data) { 252 | formData.thumbnailFilename = data.value; 253 | // console.log(formData.thumbnailFilename); 254 | }) 255 | .getValue('input#ClipTime').then(function(val) { 256 | formData.lengthMinutes = val * 1; 257 | // console.log(formData.lengthMinutes); 258 | }) 259 | .getValue('#producerUploadedPreview').then(function(val) { 260 | formData.trailerFilename = val; 261 | }) 262 | .getValue("#fut_month").then(function(val) { 263 | dateObj.mm = val; 264 | }) 265 | .getValue("#fut_day").then(function(val) { 266 | dateObj.dd = val; 267 | }) 268 | .getValue("#fut_year").then(function(val) { 269 | dateObj.yyyy = val; 270 | }) 271 | .getValue("#fut_hour").then(function(val) { 272 | dateObj.HH = val; 273 | }) 274 | .getValue("#fut_minute").then(function(val) { 275 | dateObj.MM = val; 276 | // console.log(dateObj); 277 | // console.log(dateutil.parse(dateObj.yyyy+"-"+dateObj.mm+"-"+dateObj.dd+" "+dateObj.HH+":"+dateObj.MM).toISOString()); 278 | formData.releaseDate = dateutil.parse(dateObj.yyyy + "-" + dateObj.mm + "-" + dateObj.dd + " " + dateObj.HH + ":" + dateObj.MM).toISOString(); 279 | }) 280 | 281 | // Success Callback 282 | .next(function() { 283 | params.client.end(); /** Ends browser session {@link editVid| read editVids docs} */ 284 | console.log('Done!'); 285 | console.log(JSON.stringify(formData, null, 2)); 286 | return callback(null, formData); 287 | }) 288 | 289 | // Global Error Callback 290 | .catch((e) => { 291 | console.log(e); 292 | params.client.end(); /** Ends browser session {@link editVid| read editVids docs} */ 293 | // params.client.session('delete'); /** Ends browser session {@link editVid| read editVids docs} */ 294 | return callback(e, {}); 295 | }); 296 | }; 297 | 298 | /** 299 | * Create New Clip 300 | * @param {Integer} event The clip data 301 | * @param {Object} params client, cookie 302 | * @param {Function} callback [description] 303 | * @return {Object} [description] 304 | */ 305 | function postClip(event, params, callback) { 306 | var tagCount = event.tags.length; 307 | 308 | // Remove . and / from titles per C4S 309 | var name = event.name.replace('.', '').replace('/', ''); 310 | console.log(`Clean Title: ${name}`); 311 | var description = `${event.description}`; 312 | var d = { 313 | mm: dateFormat(event.releaseDate, "mm"), 314 | d: dateFormat(event.releaseDate, "d"), 315 | yyyy: dateFormat(event.releaseDate, "yyyy"), 316 | HH: dateFormat(event.releaseDate, "HH"), 317 | MM: dateFormat(event.releaseDate, "MM"), 318 | }; 319 | var response = {}; 320 | console.log(event, params); // Debug 321 | 322 | if (!event.thumbnailFilename) { 323 | event.thumbnailFilename = -2; 324 | } 325 | if (!event.trailerFilename) { 326 | event.trailerFilename = ''; 327 | } 328 | 329 | params.client 330 | // .init() 331 | // .setCookie(params.cookie) 332 | .url('https://admin.clips4sale.com/clips/index') 333 | .execute(function() { 334 | // window.addEventListener("beforeunload", function (e) { 335 | // var confirmationMessage = "\o/"; 336 | // 337 | // (e || window.event).returnValue = confirmationMessage; //Gecko + IE 338 | // return confirmationMessage; //Webkit, Safari, Chrome 339 | // }); 340 | }) 341 | .waitForVisible('input[name="ClipTitle"]', 30000) 342 | // .setValue('[name="ClipTitle"]', event.name + map.get(event.flavor)) 343 | .setValue('input[name="ClipTitle"]', name).pause(200) 344 | .getAttribute('input[name="producer_id"]', 'value').then(function(val) { 345 | // console.log('category is: ' + JSON.stringify(val)); 346 | event.producer_id = val * 1; 347 | console.log(event.producer_id); 348 | }) 349 | 350 | /* TRAILERS */ 351 | // .execute(function(event) { 352 | // console.log("Selecting the trailer file.", event.trailerFilename.replace(/^.*[\\\/]/, '')); 353 | // $('#clip_preview').val(event.trailerFilename); 354 | // }, event) 355 | 356 | /* VIDEO FILE */ 357 | // .execute(function(event) { 358 | // $('#ClipImage').val(event.thumbnailFilename); 359 | // }, event) 360 | 361 | /* VIDEO FILE */ 362 | // .execute(function(event) { 363 | // $('#ClipName').val(event.filename.replace(/^.*[\\\/]/, '')); 364 | // }, event).pause(1000) 365 | 366 | /** PRODUCER ID */ 367 | .execute(function(data) { 368 | var data = {}; 369 | data.producer_id = $('input[name="producer_id"]')[0].value * 1; 370 | console.log(data); 371 | return data; 372 | }).then(function(data) { 373 | event.producer_id = data.producer_id; 374 | console.log(data.producer_id); 375 | // event.clip_id = data.clip_id; 376 | }) 377 | .execute(function(description) { 378 | console.log(description); 379 | var cleanDesc = description.replace(/kid|hooker|teenager|force|forced|forcing|teenie/g, ''); 380 | // browser context - you may not access client or console 381 | tinyMCE.activeEditor.setContent(`${cleanDesc}`, { 382 | format: "raw" 383 | }); 384 | }, description) 385 | // .selectByValue('select#ClipName', path.basename(event.filename) || 'Select File-->').catch(function(err) { 386 | // response.err = err; 387 | // response.msg = 'Error: Video file not found in uploads.'; 388 | // // params.client.end(); /** Ends browser session {@link editVid| read editVids docs} */ 389 | // console.log(response); 390 | // // return callback(err, response); // Don't send error to clipnuke.com 391 | // }).pause(1000) 392 | // .selectByVisibleText('[name="ClipCat"]', event.category) 393 | // .selectByValue("[name='fut_month']", dateFormat(event.releaseDate, "mm") || dateFormat(getDate(), "mm")).pause(200) 394 | .selectByVisibleText('select#keycat', event.category).catch(function(err) { 395 | response.err = err; 396 | response.msg = 'Error: Category 1 Not Found.'; 397 | // params.client.end(); /** Ends browser session {@link editVid| read editVids docs} */ 398 | console.log(response); 399 | params.client.end(); 400 | return callback(err, response); 401 | }).pause(200) 402 | .selectByVisibleText('select#key1', event.relatedCategories[0] || 'Select Related Categories').catch(function(err) { 403 | response.err = err; 404 | response.msg = 'Error: Category 2 Not Found.'; 405 | // params.client.end(); /** Ends browser session {@link editVid| read editVids docs} */ 406 | console.log(response); 407 | params.client.end(); 408 | return callback(err, response); 409 | }).pause(200) 410 | .selectByVisibleText('select#key2', event.relatedCategories[1] || 'Select Related Categories').catch(function(err) { 411 | response.err = err; 412 | response.msg = 'Error: Category 3 Not Found.'; 413 | // params.client.end(); /** Ends browser session {@link editVid| read editVids docs} */ 414 | console.log(response); 415 | params.client.end(); 416 | return callback(err, response); 417 | }).pause(200) 418 | .selectByVisibleText('select#key3', event.relatedCategories[2] || 'Select Related Categories').catch(function(err) { 419 | response.err = err; 420 | response.msg = 'Error: Category 4 Not Found.'; 421 | // params.client.end(); /** Ends browser session {@link editVid| read editVids docs} */ 422 | console.log(response); 423 | params.client.end(); 424 | return callback(err, response); 425 | }).pause(200) 426 | .selectByVisibleText('select#key4', event.relatedCategories[3] || 'Select Related Categories').catch(function(err) { 427 | response.err = err; 428 | response.msg = 'Error: Category 5 Not Found.'; 429 | // params.client.end(); /** Ends browser session {@link editVid| read editVids docs} */ 430 | console.log(response); 431 | params.client.end(); 432 | return callback(err, response); 433 | }).pause(200) 434 | .selectByVisibleText('select#key5', event.relatedCategories[4] || 'Select Related Categories').catch(function(err) { 435 | response.err = err; 436 | response.msg = 'Error: Category 6 Not Found.'; 437 | // params.client.end(); /** Ends browser session {@link editVid| read editVids docs} */ 438 | console.log(response); 439 | params.client.end(); 440 | return callback(err, response); 441 | }).pause(200) 442 | 443 | /** TAGS */ 444 | // Remove teenie 445 | .setValue('input[name="keytype[0]"]', event.tags[0] || '').pause(200) 446 | .setValue('input[name="keytype[1]"]', event.tags[1] || '').pause(200) 447 | .setValue('input[name="keytype[2]"]', event.tags[2] || '') 448 | .setValue('input[name="keytype[3]"]', event.tags[3] || '') 449 | .setValue('input[name="keytype[4]"]', event.tags[4] || '') 450 | .setValue('input[name="keytype[5]"]', event.tags[5] || '') 451 | .setValue('input[name="keytype[6]"]', event.tags[6] || '') 452 | .setValue('input[name="keytype[7]"]', event.tags[7] || '') 453 | .setValue('input[name="keytype[8]"]', event.tags[8] || '') 454 | .setValue('input[name="keytype[9]"]', event.tags[9] || '') 455 | .setValue('input[name="keytype[10]"]', event.tags[10] || '') 456 | .setValue('input[name="keytype[11]"]', event.tags[11] || '') 457 | .setValue('input[name="keytype[12]"]', event.tags[12] || '') 458 | .setValue('input[name="keytype[13]"]', event.tags[13] || '') 459 | .setValue('input[name="keytype[14]"]', event.tags[14] || '') 460 | .setValue('input[name="DisplayOrder"]', event.displayOrder || 0) 461 | .selectByValue("#fut_month", d.mm || dateFormat(getDate(), "mm")).pause(100) 462 | .selectByValue("#fut_day", d.d || dateFormat(getDate(), "dd")).pause(100) 463 | .selectByValue("#fut_year", d.yyyy || dateFormat(getDate(), "yyyy")).pause(100) 464 | .selectByValue("#fut_hour", d.HH || dateFormat(getDate(), "HH")).pause(100) 465 | .selectByValue("#fut_minute", d.MM || dateFormat(getDate(), "MM")).pause(100) 466 | // .waitForVisible('#fullwide > div.container-fluid > div.alert.alert-success', 900000).pause(10000) 467 | 468 | /* THUMBNAIL */ 469 | // .selectByValue('#ClipImage', path.basename(event.thumbnailFilename) || 'Generate an animated gif banner').catch(function(err) { 470 | // response.err = err; 471 | // response.msg = 'Error: Thumbnail not found in uploads.'; 472 | // // params.client.end(); /** Ends browser session {@link editVid| read editVids docs} */ 473 | // console.log(response); 474 | // // return callback(err, response); // Don't send error to clipnuke.com 475 | // }).pause(2000) 476 | 477 | /* TRAILER */ 478 | // .selectByValue('select#clip_preview', path.basename(event.trailerFilename) || '').catch(function(err) { 479 | // response.err = err; 480 | // response.msg = 'Error: Trailer not found in uploads.'; 481 | // // params.client.end(); /** Ends browser session {@link editVid| read editVids docs} */ 482 | // console.log(response); 483 | // // return callback(err, response); // Don't send error to clipnuke.com 484 | // }).pause(2000) 485 | 486 | // .selectByValue('#clip_price', event.price).catch(function(err) { 487 | // response.err = err; 488 | // response.msg = 'Error: Cannot Select a price.'; 489 | // // params.client.end(); /** Ends browser session {@link editVid| read editVids docs} */ 490 | // console.log(response); 491 | // // return callback(err, response); // Don't send error to clipnuke.com 492 | // }).pause(2000) 493 | // .setValue('[name="ContainsNudity"]', event.containsNudity || 1) 494 | // .setValue('[name="members"]', event.members || 1 ) 495 | // .setValue('[name="ClipActive"]', event.clipActive || 1) 496 | // .setValue('[name="use_future"]', event.useFuture || 0) 497 | // .click('#submitButton') 498 | // .pause(2000) 499 | // .waitForVisible('#fullwide > div.container-fluid > div.alert.alert-success', 900000).pause(10000) 500 | .waitUntil(() => { 501 | return window.location.href.indexOf('?c=') != -1 502 | }, 900000) 503 | // .getValue('input[name="id"]').then(function(val) { 504 | // // console.log('Studio ID is: ' + JSON.stringify(val)); 505 | // console.log(val); 506 | // event.clip_id = val*1; 507 | // }) 508 | // .execute(function(event) { 509 | // var urlParams = new URLSearchParams(window.location.search); 510 | // var data = {}; 511 | // data.clip_id = urlParams.get('c')*1; 512 | // 513 | // console.log(urlParams.has('c')); // true 514 | // console.log(urlParams.get('c')); // "edit" 515 | // return data.clip_id; 516 | // }).then(function(data) { 517 | // event.clip_id = data.value; 518 | // console.log(event.clip_id); 519 | // }) 520 | // .click("#c4sTweet").pause(1000) 521 | // .then(function(){ 522 | // params.client.end(); 523 | // }) 524 | /* .waitUntil(function () { 525 | console.log(window.clip_id); 526 | return window.clip_id == undefined; 527 | // return $( 'input[name="id"]' )[0].value != ""; 528 | }, 5000, 'Error: waitUntil Clip ID (id) field is visible failed.') */ 529 | /* .waitUntil(function() { 530 | return params.client.execute(function() { 531 | function() { 532 | var val = 533 | return val; 534 | } 535 | return window.clip_id != undefined; 536 | }).then(function(result) { 537 | console.log(result); 538 | event.clip_id = result; 539 | return result; 540 | }); 541 | }, params) */ 542 | // .selectByValue('[name="ClipPrice"]', event.price) 543 | /* .waitForVisible('.alert.alert-success', 20000) 544 | .execute(function(data) { 545 | // event.clip_id = clip_id*1; 546 | event.producer_id = $('input[name="producer_id"]')[0].value*1; 547 | event.clip_id = $('input[name="clip_id"]')[0].value*1; 548 | console.log(JSON.stringify(event, null, 2)); 549 | return event; 550 | }) */ 551 | // .then(function(data) { 552 | // event.clip_id = data.value*1; 553 | // console.log(event.clip_id); 554 | // }) 555 | 556 | // Success Callback 557 | .then(function(data) { 558 | console.log(data); 559 | params.client 560 | /* .waitForVisible('[name="ClipTitle"]', 3000) 561 | .execute(function(data) { 562 | data.clip_id = clip_id*1; 563 | return data.clip_id; 564 | }, data).then(function(data) { 565 | event.clip_id = data.value*1; 566 | console.log(event.clip_id); 567 | }) 568 | .getValue('[name="id').then(function(val) { 569 | console.log('Clip ID: ' + JSON.stringify(val)); 570 | if(val !== null && val !== '') { 571 | event.clip_id = val; 572 | } 573 | }) */ 574 | .end(); 575 | console.log('Done!'); 576 | console.log(JSON.stringify(event, null, 2)); 577 | 578 | return callback(null, event); 579 | }) 580 | 581 | // Global Error Callback 582 | .catch((e) => { 583 | // params.client.end(); 584 | // params.client.session('delete'); 585 | console.log(e); 586 | return callback(e); 587 | }); 588 | }; 589 | 590 | module.exports = { 591 | login: auth, 592 | getClip: getClip, 593 | postClip: postClip 594 | }; 595 | -------------------------------------------------------------------------------- /api/routes/clips4sale/cookie.json: -------------------------------------------------------------------------------- 1 | { 2 | "domain":".clips4sale.com", 3 | "expiry":1520927551.376236, 4 | "httpOnly":true, 5 | "name":"PHPSESSID", 6 | "path":"/", 7 | "secure":false, 8 | "value":"rb1kb7j0t2k1pbja6agg8trkd1" 9 | } 10 | -------------------------------------------------------------------------------- /api/routes/clips4sale/ftp/ftpHelper.js: -------------------------------------------------------------------------------- 1 | var hyperquest = require('hyperquest'); 2 | var fs = require('fs'); 3 | var path = require('path'); 4 | var Client = require('ftp'); 5 | var Minio = require('minio'); 6 | 7 | function upload(event, callback) { 8 | 9 | var dstFile = path.basename(event.url); 10 | var ext = path.extname(event.url); 11 | var dstPath; 12 | if (ext == ".mp4" || ".wmv" || ".mov" || ".avi") { 13 | dstPath = '/clips'; 14 | } else if (ext == ".jpg" || ".gif" || ".png" || ".jpeg" || ".tiff" || ".tif") { 15 | dstPath = '/clip_images'; 16 | } 17 | switch (event.type) { 18 | case "trailer": 19 | dstPath = '/clips_previews'; 20 | break; 21 | case "video": 22 | dstPath = '/clips'; 23 | break; 24 | case "poster": 25 | dstPath = '/clip_images'; 26 | break; 27 | } 28 | console.log('File: ', dstFile) 29 | 30 | function search(nameKey, myArray) { 31 | for (var i = 0; i < myArray.length; i++) { 32 | if (myArray[i].name === nameKey) { 33 | return myArray[i]; 34 | } 35 | } 36 | } 37 | 38 | var ftpClient = new Client(); 39 | 40 | ftpClient.connect({ 41 | host: 'ftp.clips4sale.com', 42 | user: conf.settings.clips4sale.user, 43 | password: conf.settings.clips4sale.pass 44 | }); 45 | 46 | ftpClient.on('ready', function() { 47 | 48 | /* var src = request({ 49 | url: event.url, 50 | method: "HEAD" 51 | }, function(err, response, body) { 52 | console.log(response.headers); 53 | return response.headers; 54 | // process.exit(0); 55 | }); */ 56 | // console.log(size); 57 | 58 | /** Change directory on FTP server */ 59 | ftpClient.cwd(dstPath, function(err, currentDir) { 60 | if (err) throw err; 61 | console.log(`Directory changed to ${dstPath}`); 62 | 63 | ftpClient.list(dstPath, function(err, data) { 64 | // console.log(JSON.stringify(data, null, 2)); // Debug 65 | if (err) { 66 | console.log(err); 67 | } 68 | var obj = search(dstFile, data); 69 | console.log(obj); 70 | // console.log('File Size: ' + obj.size + ' Bytes'); 71 | // console.log(src, obj.size); 72 | 73 | if (obj) { 74 | ftpClient.end(); 75 | console.log('File already exists on destination server\'s filesystem.'); 76 | callback(null, obj); 77 | // process.exit(0); 78 | } else { 79 | 80 | if (event.type == "video" || event.type == "trailer") { 81 | 82 | // Allow insecure TLS connections 83 | process.env['NODE_TLS_REJECT_UNAUTHORIZED'] = '0'; 84 | 85 | // Setup minio client 86 | var minioClient = new Minio.Client({ 87 | endPoint: conf.settings.s3.endpoint, 88 | port: conf.settings.s3.port, 89 | useSSL: conf.settings.s3.use_ssl || true, 90 | accessKey: conf.settings.s3.access_key, 91 | secretKey: conf.settings.s3.secret_key 92 | }); 93 | 94 | var size = 0; 95 | 96 | // Grab our video file from an s3-compatible server and stream (dataStream) 97 | minioClient.getObject(conf.settings.s3.bucket_name, event.url, function(err, dataStream) { 98 | if (err) { 99 | return console.log(err) 100 | } 101 | dataStream.on('data', function(chunk) { 102 | size += chunk.length 103 | }) 104 | dataStream.on('end', function() { 105 | console.log('End. Total size = ' + size) 106 | }) 107 | dataStream.on('error', function(err) { 108 | console.log(err) 109 | }) 110 | 111 | console.time("upload"); 112 | 113 | // Pipe stream to destination FTP server 114 | ftpClient.put(dataStream, dstFile, function(err) { 115 | if (err) { 116 | console.log(err); 117 | } 118 | ftpClient.end(); 119 | console.timeEnd("upload"); 120 | console.log("Finished"); 121 | }); 122 | }); 123 | } else { 124 | 125 | // Grab from HTTP request and stream 126 | var stream = hyperquest(event.url); 127 | console.time("upload"); 128 | 129 | // Pipe stream to destination FTP server 130 | ftpClient.put(stream, dstFile, function(err) { 131 | if (err) { 132 | console.log(err); 133 | } 134 | ftpClient.end(); 135 | console.timeEnd("upload"); 136 | console.log("Finished"); 137 | }); 138 | } 139 | } 140 | }); 141 | }); 142 | 143 | }); 144 | 145 | var upload = function() { 146 | ftpClient.size(dstFile, function(err, size) { 147 | // Assuming the err is the file not existing, good enough for now 148 | // err.code will give the exact status code otherwise (550 is file not found) 149 | var stream = hyperquest('event.url'); 150 | if (err) { 151 | 152 | hyperquest('event.url').pipe(res)(function(res) { 153 | // console.log(stream); 154 | ftpClient.put(stream, dstFile, function(err) { 155 | if (err) { 156 | console.log(err); 157 | } 158 | ftpClient.end(); 159 | console.timeEnd("upload"); 160 | console.log("Finished"); 161 | }); 162 | }); 163 | 164 | } else { 165 | 166 | console.log("Resuming download at start: " + size); 167 | getFileFromS3(size, function(res) { 168 | 169 | ftpClient.append(res, dstFile, function(err) { 170 | if (err) { 171 | console.log(err); 172 | } 173 | 174 | ftpClient.end(); 175 | console.timeEnd("upload"); 176 | console.log("Finished"); 177 | }); 178 | }); 179 | 180 | } 181 | }); 182 | }; 183 | 184 | ftpClient.on('close', function(hadError) { 185 | if (hadError) { 186 | console.log("FTP server closed with an error"); 187 | // callback("FTP server closed with an error"); 188 | } else { 189 | console.log("FTP server closed"); 190 | // done(); 191 | } 192 | }); 193 | 194 | ftpClient.on('error', function(err) { 195 | console.log("FTP server had error: " + err); 196 | }); 197 | 198 | 199 | ftpClient.on('end', function() { 200 | console.log("FTP server ended connection"); 201 | }); 202 | 203 | ftpClient.on('greeting', function(msg) { 204 | console.log(msg); 205 | }); 206 | 207 | } 208 | 209 | function httpUpload(event, callback) { 210 | 211 | var dstFile = path.basename(event.url); 212 | var ext = path.extname(event.url); 213 | var dstPath; 214 | if (ext == ".mp4" || ".wmv" || ".mov" || ".avi") { 215 | dstPath = '/clips'; 216 | } else if (ext == ".jpg" || ".gif" || ".png" || ".jpeg" || ".tiff" || ".tif") { 217 | dstPath = '/clip_images'; 218 | } 219 | switch (event.type) { 220 | case "trailer": 221 | dstPath = '/clips_previews'; 222 | break; 223 | case "video": 224 | dstPath = '/clips'; 225 | break; 226 | case "poster": 227 | dstPath = '/clip_images'; 228 | break; 229 | } 230 | console.log('File: ', dstFile) 231 | 232 | function search(nameKey, myArray) { 233 | for (var i = 0; i < myArray.length; i++) { 234 | if (myArray[i].name === nameKey) { 235 | return myArray[i]; 236 | } 237 | } 238 | } 239 | 240 | var ftpClient = new Client(); 241 | 242 | ftpClient.connect({ 243 | host: 'ftp.clips4sale.com', 244 | user: conf.settings.clips4sale.user, 245 | password: conf.settings.clips4sale.pass 246 | }); 247 | 248 | ftpClient.on('ready', function() { 249 | 250 | /** Change directory on FTP server */ 251 | ftpClient.cwd(dstPath, function(err, currentDir) { 252 | if (err) throw err; 253 | console.log(`Directory changed to ${dstPath}`); 254 | 255 | ftpClient.list(dstPath, function(err, data) { 256 | // console.log(JSON.stringify(data, null, 2)); // Debug 257 | if (err) { 258 | console.log(err); 259 | } 260 | var obj = search(dstFile, data); 261 | console.log(obj); 262 | // console.log('File Size: ' + obj.size + ' Bytes'); 263 | // console.log(src, obj.size); 264 | 265 | if (obj) { 266 | ftpClient.end(); 267 | console.log('File already exists on destination server\'s filesystem.'); 268 | callback(null, obj); 269 | // process.exit(0); 270 | } else { 271 | 272 | // Grab from HTTP request and stream 273 | var stream = hyperquest(event.url); 274 | console.time("upload"); 275 | 276 | // Pipe stream to destination FTP server 277 | ftpClient.put(stream, dstFile, function(err) { 278 | if (err) { 279 | console.log(err); 280 | } 281 | ftpClient.end(); 282 | console.timeEnd("upload"); 283 | console.log("Finished"); 284 | }); 285 | } 286 | }); 287 | }); 288 | }); 289 | 290 | var upload = function() { 291 | ftpClient.size(dstFile, function(err, size) { 292 | // Assuming the err is the file not existing, good enough for now 293 | // err.code will give the exact status code otherwise (550 is file not found) 294 | var stream = hyperquest('event.url'); 295 | if (err) { 296 | 297 | hyperquest('event.url').pipe(res)(function(res) { 298 | // console.log(stream); 299 | ftpClient.put(stream, dstFile, function(err) { 300 | if (err) { 301 | console.log(err); 302 | } 303 | ftpClient.end(); 304 | console.timeEnd("upload"); 305 | console.log("Finished"); 306 | }); 307 | }); 308 | 309 | } else { 310 | 311 | console.log("Resuming download at start: " + size); 312 | getFileFromS3(size, function(res) { 313 | 314 | ftpClient.append(res, dstFile, function(err) { 315 | if (err) { 316 | console.log(err); 317 | } 318 | 319 | ftpClient.end(); 320 | console.timeEnd("upload"); 321 | console.log("Finished"); 322 | }); 323 | }); 324 | 325 | } 326 | }); 327 | }; 328 | 329 | ftpClient.on('close', function(hadError) { 330 | if (hadError) { 331 | console.log("FTP server closed with an error"); 332 | // callback("FTP server closed with an error"); 333 | } else { 334 | console.log("FTP server closed"); 335 | // done(); 336 | } 337 | }); 338 | 339 | ftpClient.on('error', function(err) { 340 | console.log("FTP server had error: " + err); 341 | }); 342 | 343 | 344 | ftpClient.on('end', function() { 345 | console.log("FTP server ended connection"); 346 | }); 347 | 348 | ftpClient.on('greeting', function(msg) { 349 | console.log(msg); 350 | }); 351 | 352 | } 353 | 354 | module.exports = { 355 | upload: upload, 356 | httpUpload: httpUpload 357 | }; 358 | -------------------------------------------------------------------------------- /api/routes/clips4sale/ftp/index.js: -------------------------------------------------------------------------------- 1 | var ftp = require('express').Router({ 2 | mergeParams: true 3 | }); 4 | var path = require('path'); 5 | var bodyParser = require('body-parser') 6 | var jsonParser = bodyParser.json() 7 | 8 | // clips4sale Helper 9 | const ftpHelper = require('./ftpHelper.js'); 10 | 11 | const conf = require(path.join(process.env.APPDATA, "clipnuke", "config.json")); 12 | 13 | ftp.post('/', jsonParser, function(req, res) { 14 | var event = req.body; 15 | const credentials = { 16 | user: conf.settings.clips4sale.user, 17 | pass: conf.settings.clips4sale.pass 18 | }; 19 | // console.log(req, res); 20 | event.credentials = []; 21 | event.credentials.push(credentials); 22 | console.log(event); 23 | ftpHelper.httpUpload(req.body, function(err, data) { 24 | if (err) { 25 | callback(err, data); 26 | } else { 27 | console.log(data); 28 | res.status(200).json(data); 29 | } 30 | }); 31 | // console.log(req.body); // your JSON 32 | // res.send(req.body); // echo the result back 33 | 34 | }); 35 | 36 | module.exports = ftp; 37 | -------------------------------------------------------------------------------- /api/routes/clips4sale/index.js: -------------------------------------------------------------------------------- 1 | const clips4sale = require('express').Router({ 2 | mergeParams: true 3 | }); 4 | const path = require('path'); 5 | const fs = require('fs'); 6 | const sales = require(path.join(__dirname, 'sales')) 7 | const ftp = require(path.join(__dirname, 'ftp')) 8 | const bodyParser = require('body-parser') 9 | const jsonParser = bodyParser.json() 10 | const spawn = require('child_process').spawn; // TODO Change to fork 11 | var cp = require('child_process'); 12 | 13 | // clips4sale Helper 14 | const c4s = require(path.join(__dirname, 'c4sHelper.js')); 15 | 16 | // Webdriver Client Instance 17 | // Webdriver Client Instance 18 | var webdriverio = require('webdriverio'); 19 | var config = { 20 | desiredCapabilities: { 21 | browserName: 'chrome', 22 | chromeOptions: { 23 | binary: path.join(__dirname, '../../../../bin/chromedriver.exe') 24 | }, 25 | }, 26 | singleton: true, // Enable persistent sessions 27 | debug: true, 28 | // host: "http://127.0.0.1", 29 | // port: 4444 30 | }; 31 | var client = webdriverio.remote(config); 32 | // const client = require(path.join(__dirname, '../../webdriverio/client.js')).client; 33 | // console.log(client); 34 | 35 | try { 36 | if (fs.existsSync(path.join(__dirname, '../../../../webdriverio/client.js'))) { 37 | console.log('WebDriverIO Client Found!'); 38 | //file exists 39 | } 40 | } catch (err) { 41 | console.error(err) 42 | console.log('WDIO client not found.'); 43 | } 44 | /* const webdriverio = require('webdriverio'); 45 | const config = { 46 | desiredCapabilities: { 47 | browserName: 'chrome', 48 | chromeOptions: { 49 | binary: path.join(__dirname, '../../../../bin/chromedriver.exe') 50 | }, 51 | }, 52 | singleton:true, // Enable persistent sessions 53 | debug: true, 54 | host: "http://127.0.0.1", 55 | port: 4444 56 | }; 57 | var client = webdriverio.remote(config); */ 58 | 59 | console.log(path.join(__dirname, '../../../../bin/chromedriver.exe')); 60 | 61 | // Test cookie - Pre-authenticated 62 | // const cookie = require('./cookie.json'); 63 | 64 | // Test Route 65 | clips4sale.get('/', (req, res) => { 66 | res.status(200).json({ 67 | message: 'Clips4Sale API' 68 | }); 69 | }); 70 | 71 | clips4sale.post('/spawn', jsonParser, (req, res) => { 72 | const event = req.body; 73 | var child = cp.fork(path.join(__dirname, 'postClip.js'), [JSON.stringify(event)]); 74 | // let child = spawn( 75 | // 'node', 76 | // [ 77 | // path.join(__dirname, 'postClip.js'), 78 | // JSON.stringify(event) 79 | // ] 80 | // ); 81 | // var buf = Buffer.from(JSON.stringify(event)); 82 | // child.stdin.write(buf); 83 | // child.stdin.end(); 84 | child.on('exit', (code) => { 85 | console.log(`Child process exited with code ${code}`); 86 | // if (code === 0) { 87 | // res.status(200).json({ message: 'WebDriverIO ran successfully.' }); 88 | // } 89 | // res.status(200).json({ message: 'xxxmultimedia.com Router!' }); 90 | }); 91 | child.stdout.on('data', (data) => { 92 | console.log(`stdout: ${data}`); 93 | // res.status(200).json(data); 94 | }); 95 | child.stderr.on('data', (data) => { 96 | console.log(`stderr: ${data}`); 97 | // res.status(400).json(data); 98 | }); 99 | }); 100 | 101 | // List Clips 102 | clips4sale.get('/clips', function(req, res) { 103 | if (!req.header('X-Cookie')) { 104 | res.status(401).send('Missing X-Cookie Header'); 105 | } else { 106 | const id = req.params.id; 107 | console.log(`GET /clips - Mock Endpoint`); // Mock 108 | res.json({}); 109 | } 110 | }); 111 | 112 | // route to trigger the capture 113 | clips4sale.post('/clips', jsonParser, function(req, res) { 114 | if (!req.headers.authorization || req.headers.authorization.split(' ')[0] !== 'Bearer' || !req.header('X-Cookie')) { 115 | res.status(401).send('Missing Authentication Method.'); 116 | } else { 117 | const event = req.body; 118 | const user = req.headers.authorization.split(' ')[1].split(':')[0]; 119 | const pass = req.headers.authorization.split(' ')[1].split(':')[1]; 120 | // console.log(JSON.stringify(event, null, 2)); // Mock 121 | const credentials = { 122 | user: user || event["credentials"][0]["c4s_username"] || process.env.C4S_USER, 123 | pass: pass || event["credentials"][0]["c4s_password"] || process.env.C4S_PASS, 124 | phpsessid: req.header('X-Cookie') || event["credentials"][0]["c4s_phpsessid"] 125 | }; 126 | const params = { 127 | client: client, 128 | cookie: cookie 129 | }; 130 | // console.log(credentials); // Debug 131 | c4s.login(credentials, params, function(err, data) { 132 | c4s.postClip(event, params, function(err, data) { 133 | console.log(data); 134 | res.json(data); 135 | }); 136 | }); 137 | } 138 | }); 139 | 140 | // route to trigger the capture 141 | clips4sale.get('/clips/:id', function(req, res) { 142 | if (!req.headers.authorization || req.headers.authorization.split(' ')[0] !== 'Bearer' || !req.header('X-Cookie')) { 143 | res.status(401).send('Missing Authentication Method.'); 144 | } else { 145 | const id = req.params.id; 146 | console.log(`Requesting Clip ID: ${id}`); 147 | const user = req.headers.authorization.split(' ')[1].split(':')[0]; 148 | const pass = req.headers.authorization.split(' ')[1].split(':')[1]; 149 | const credentials = { 150 | user: user || event["credentials"][0]["c4s_username"] || process.env.C4S_USER, 151 | pass: pass || event["credentials"][0]["c4s_password"] || process.env.C4S_PASS, 152 | phpsessid: req.header('X-Cookie') || process.env.C4S_PHPSESSID || event["credentials"][0]["c4s_phpsessid"] 153 | }; 154 | const params = { 155 | client: client 156 | }; 157 | 158 | c4s.login(credentials, params, function(err, data) { 159 | c4s.getClip(id, params, function(err, data) { 160 | if (err) { 161 | console.log(err); 162 | res.send(401, err); 163 | } else { 164 | console.log(data); 165 | res.json(data); 166 | } 167 | }); 168 | }); 169 | } 170 | }); 171 | 172 | // route to trigger the capture 173 | clips4sale.put('/clips/:id', function(req, res) { 174 | if (!req.header('X-Cookie')) { 175 | res.status(401).send('Missing X-Cookie Header'); 176 | } else { 177 | const id = req.params.id; 178 | console.log(`PUT /clips/${id} - Mock Endpoint`); // Mock 179 | res.json({}); 180 | } 181 | }); 182 | 183 | // route to trigger the capture 184 | clips4sale.delete('/clips/:id', function(req, res) { 185 | if (!req.header('X-Cookie')) { 186 | res.status(401).send('Missing X-Cookie Header'); 187 | } else { 188 | const id = req.params.id; 189 | console.log(`DELETE /clips/${id} - Mock Endpoint`); // Mock 190 | res.json({}); 191 | } 192 | }); 193 | 194 | /** 195 | * Clips4Sale Router 196 | * @type {String} 197 | */ 198 | clips4sale.use('/sales', sales); 199 | 200 | clips4sale.use('/ftp', ftp); 201 | 202 | module.exports = clips4sale; 203 | -------------------------------------------------------------------------------- /api/routes/clips4sale/postClip.js: -------------------------------------------------------------------------------- 1 | const dateutil = require('dateutil'); 2 | const dateFormat = require('dateformat'); 3 | var fs = require('fs'); 4 | var path = require('path'); 5 | var webdriverio = require('webdriverio'); 6 | const spawn = require('child_process').spawn; // TODO Change to fork 7 | 8 | // Webdriver Client Instance 9 | var config = { 10 | desiredCapabilities: { 11 | browserName: 'chrome', 12 | chromeOptions: { 13 | binary: path.join(__dirname, '../../../../bin/chromedriver.exe') 14 | }, 15 | }, 16 | singleton: true, // Enable persistent sessions 17 | debug: true, 18 | // host: "http://127.0.0.1", 19 | // port: 4444 20 | }; 21 | var client = webdriverio.remote(config); 22 | const conf = require(path.join(process.env.APPDATA, "clipnuke", "config.json")) 23 | // let settings = fs.readFileSync(path.join(process.env.APPDATA, "clipnuke", "config.json")); 24 | console.log(conf); 25 | 26 | console.log(process.argv); 27 | var event = JSON.parse(process.argv[2]); 28 | 29 | // ETL 30 | var tagCount = event.tags.length; 31 | // Remove . and / from titles per C4S 32 | var name = event.name.replace('.', '').replace('/', ''); 33 | console.log(`Clean Title: ${name}`); 34 | var description = `${event.description}`; 35 | var d = { 36 | mm: dateFormat(event.releaseDate, "mm"), 37 | d: dateFormat(event.releaseDate, "d"), 38 | yyyy: dateFormat(event.releaseDate, "yyyy"), 39 | HH: dateFormat(event.releaseDate, "HH"), 40 | MM: dateFormat(event.releaseDate, "MM"), 41 | }; 42 | var response = {}; 43 | console.log(event); // Debug 44 | 45 | // Set defaults if not set -- so this script doesn't throw exceptions 46 | if (!event.filename) { 47 | event.filename = ''; 48 | } else { 49 | event.filename = path.parse(event.filename).base; // Get filename 50 | } 51 | if (!event.thumbnailFilename) { 52 | event.thumbnailFilename = -2; 53 | } else { 54 | event.thumbnailFilename = path.parse(event.thumbnailFilename).base; // Get filename 55 | } 56 | if (!event.trailerFilename) { 57 | event.trailerFilename = ''; 58 | } else { 59 | event.trailerFilename = path.parse(event.trailerFilename).base; // Get filename 60 | } 61 | 62 | client 63 | .init() 64 | .url('https://admin.clips4sale.com/login/index') 65 | .waitForVisible('input#username', 3000) 66 | .setValue('input#username', conf.settings.clips4sale.user) 67 | .setValue('input#password', conf.settings.clips4sale.pass).pause(200) 68 | // .submitForm('input.btn-primary') 69 | .click('input.btn.btn-primary') 70 | .setCookie({ 71 | domain: "admin.clips4sale.com", 72 | name: "PHPSESSID", 73 | secure: false, 74 | value: conf.settings.clips4sale.phpsessid, 75 | // expiry: seconds+3600 // When the cookie expires, specified in seconds since Unix Epoch 76 | }) 77 | .pause(1000) 78 | .url('https://admin.clips4sale.com/clips/index') 79 | .execute(function() { 80 | // window.addEventListener("beforeunload", function (e) { 81 | // var confirmationMessage = "\o/"; 82 | // 83 | // (e || window.event).returnValue = confirmationMessage; //Gecko + IE 84 | // return confirmationMessage; //Webkit, Safari, Chrome 85 | // }); 86 | }) 87 | .waitForVisible('input[name="ClipTitle"]', 30000) 88 | // .setValue('[name="ClipTitle"]', event.name + map.get(event.flavor)) 89 | .setValue('input[name="ClipTitle"]', name).pause(200) 90 | .getAttribute('input[name="producer_id"]', 'value').then(function(val) { 91 | // console.log('category is: ' + JSON.stringify(val)); 92 | event.producer_id = val * 1; 93 | console.log(event.producer_id); 94 | }) 95 | /** PRODUCER ID */ 96 | .execute(function(data) { 97 | var data = {}; 98 | data.producer_id = $('input[name="producer_id"]')[0].value * 1; 99 | console.log(data); 100 | return data; 101 | }).then(function(data) { 102 | event.producer_id = data.producer_id; 103 | console.log(data.producer_id); 104 | // event.clip_id = data.clip_id; 105 | }) 106 | .execute(function(description) { 107 | console.log(description); 108 | var cleanDesc = description.replace(/kid|xxxmultimedia.com|xxxmultimedia|hooker|teenager|force|forced|forcing|teenie/g, ''); 109 | // browser context - you may not access client or console 110 | tinyMCE.activeEditor.setContent(`${cleanDesc}`, { 111 | format: "raw" 112 | }); 113 | }, description) 114 | .selectByVisibleText('select#keycat', event.category).catch(function(err) { 115 | response.err = err; 116 | response.msg = 'Error: Category 1 Not Found.'; 117 | // client.end(); /** Ends browser session {@link editVid| read editVids docs} */ 118 | console.log(response); 119 | client.end(); 120 | // return callback(err, response); 121 | }).pause(200) 122 | .selectByVisibleText('select#key1', event.relatedCategories[0] || 'Select Related Categories').catch(function(err) { 123 | response.err = err; 124 | response.msg = 'Error: Category 2 Not Found.'; 125 | // client.end(); /** Ends browser session {@link editVid| read editVids docs} */ 126 | console.log(response); 127 | client.end(); 128 | // return callback(err, response); 129 | }).pause(200) 130 | .selectByVisibleText('select#key2', event.relatedCategories[1] || 'Select Related Categories').catch(function(err) { 131 | response.err = err; 132 | response.msg = 'Error: Category 3 Not Found.'; 133 | // client.end(); /** Ends browser session {@link editVid| read editVids docs} */ 134 | console.log(response); 135 | client.end(); 136 | // return callback(err, response); 137 | }).pause(200) 138 | .selectByVisibleText('select#key3', event.relatedCategories[2] || 'Select Related Categories').catch(function(err) { 139 | response.err = err; 140 | response.msg = 'Error: Category 4 Not Found.'; 141 | // client.end(); /** Ends browser session {@link editVid| read editVids docs} */ 142 | console.log(response); 143 | client.end(); 144 | // return callback(err, response); 145 | }).pause(200) 146 | .selectByVisibleText('select#key4', event.relatedCategories[3] || 'Select Related Categories').catch(function(err) { 147 | response.err = err; 148 | response.msg = 'Error: Category 5 Not Found.'; 149 | // client.end(); /** Ends browser session {@link editVid| read editVids docs} */ 150 | console.log(response); 151 | client.end(); 152 | // return callback(err, response); 153 | }).pause(200) 154 | .selectByVisibleText('select#key5', event.relatedCategories[4] || 'Select Related Categories').catch(function(err) { 155 | response.err = err; 156 | response.msg = 'Error: Category 6 Not Found.'; 157 | // client.end(); /** Ends browser session {@link editVid| read editVids docs} */ 158 | console.log(response); 159 | client.end(); 160 | // return callback(err, response); 161 | }).pause(200) 162 | 163 | /* TRAILERS */ 164 | .execute(function(event) { 165 | console.log("Selecting the trailer file.", event.trailerFilename.replace(/^.*[\\\/]/, '')); 166 | $('#clip_preview').val(event.trailerFilename); 167 | $('#clip_preview').trigger('change'); 168 | }, event) 169 | 170 | /* VIDEO FILE */ 171 | .execute(function(event) { 172 | $('#ClipImage').val(event.thumbnailFilename); 173 | $('#ClipImage').trigger('change'); 174 | }, event) 175 | 176 | /* VIDEO FILE */ 177 | .execute(function(event) { 178 | $('#ClipName').val(event.filename.replace(/^.*[\\\/]/, '') || ""); 179 | $('#ClipName').trigger('change'); 180 | }, event).pause(1000) 181 | 182 | /** TAGS */ 183 | // Remove teenie 184 | .setValue('input[name="keytype[0]"]', event.tags[0] || '').pause(200) 185 | .setValue('input[name="keytype[1]"]', event.tags[1] || '').pause(200) 186 | .setValue('input[name="keytype[2]"]', event.tags[2] || '') 187 | .setValue('input[name="keytype[3]"]', event.tags[3] || '') 188 | .setValue('input[name="keytype[4]"]', event.tags[4] || '') 189 | .setValue('input[name="keytype[5]"]', event.tags[5] || '') 190 | .setValue('input[name="keytype[6]"]', event.tags[6] || '') 191 | .setValue('input[name="keytype[7]"]', event.tags[7] || '') 192 | .setValue('input[name="keytype[8]"]', event.tags[8] || '') 193 | .setValue('input[name="keytype[9]"]', event.tags[9] || '') 194 | .setValue('input[name="keytype[10]"]', event.tags[10] || '') 195 | .setValue('input[name="keytype[11]"]', event.tags[11] || '') 196 | .setValue('input[name="keytype[12]"]', event.tags[12] || '') 197 | .setValue('input[name="keytype[13]"]', event.tags[13] || '') 198 | .setValue('input[name="keytype[14]"]', event.tags[14] || '') 199 | .setValue('input[name="DisplayOrder"]', event.displayOrder || 0) 200 | .selectByValue("#fut_month", d.mm || dateFormat(getDate(), "mm")).pause(100) 201 | .selectByValue("#fut_day", d.d || dateFormat(getDate(), "dd")).pause(100) 202 | .selectByValue("#fut_year", d.yyyy || dateFormat(getDate(), "yyyy")).pause(100) 203 | .selectByValue("#fut_hour", d.HH || dateFormat(getDate(), "HH")).pause(100) 204 | .selectByValue("#fut_minute", d.MM || dateFormat(getDate(), "MM")).pause(100) 205 | 206 | // .waitUntil(() => { 207 | // return window.location.href.indexOf('?c=') != -1 208 | // }, 900000) 209 | 210 | // Success Callback 211 | .then(function(data) { 212 | console.log(data); 213 | // client.end(); 214 | console.log('Done!'); 215 | console.log(JSON.stringify(event, null, 2)); 216 | 217 | // return callback(null, event); 218 | }) 219 | 220 | // Global Error Callback 221 | .catch((e) => { 222 | client.end(); 223 | // client.session('delete'); 224 | console.log(e); 225 | // return callback(e); 226 | }); 227 | -------------------------------------------------------------------------------- /api/routes/clips4sale/sales/index.js: -------------------------------------------------------------------------------- 1 | var sales = require('express').Router({ 2 | mergeParams: true 3 | }); 4 | const path = require('path'); 5 | var bodyParser = require('body-parser') 6 | var jsonParser = bodyParser.json() 7 | 8 | // clips4sale Helper 9 | const c4s = require('../c4sHelper.js'); 10 | const salesHelper = require('./salesHelper.js'); 11 | 12 | const conf = require(path.join(process.env.APPDATA, "clipnuke", "config.json")); 13 | 14 | // Test Route 15 | /** 16 | * [exports description] 17 | * @type {[type]} 18 | * @query {Integer} s_year Start Year 19 | * @query {Integer} s_month Start Month 20 | * @query {Integer} s_day Start Day 21 | * @query {Integer} e_year End Year 22 | * @query {Integer} e_month End Month 23 | * @query {Integer} e_day End Day 24 | * @query {String} report_type=detail1 Report Type 25 | * @query {String} stores=all Stores 26 | * @query {String} action=report Action 27 | */ 28 | sales.get('/', (req, res) => { 29 | // Webdriver Client Instance 30 | const client = require('../../../webdriverio/client.js').client; 31 | const credentials = { 32 | user: conf.settings.clips4sale.user, 33 | pass: conf.settings.clips4sale.pass, 34 | phpsessid: conf.settings.clips4sale.phpsessid 35 | }; 36 | const params = { 37 | client: client 38 | }; 39 | 40 | c4s.login(credentials, params, function(err, data) { 41 | if (err) { 42 | res.status(401).send('Login Error.', err); 43 | } 44 | console.log("Logged in"); 45 | salesHelper.getReport(credentials, params, req.query, function(err, data) { 46 | if (err) { 47 | console.log(err); 48 | res.send(401, err); 49 | } else { 50 | console.log(data); 51 | res.json(data); 52 | } 53 | }); 54 | }); 55 | /* salesHelper.getReport(req.query, (err, data) => { 56 | if (err) { callback(err, data); }; 57 | console.log(data); 58 | res.status(200).json(data); 59 | }); */ 60 | }); 61 | 62 | module.exports = sales; 63 | -------------------------------------------------------------------------------- /api/routes/clips4sale/sales/salesHelper.js: -------------------------------------------------------------------------------- 1 | var request = require('request'); 2 | var request = request.defaults({ 3 | jar: true 4 | }); 5 | 6 | // clips4sale Helper 7 | // const c4s = require('../c4sHelper.js'); 8 | 9 | // Webdriver Client Instance 10 | // const client = require('../../../webdriverio/client.js').client; 11 | 12 | function getReport(credentials, params, query, callback) { 13 | var reponse = {}; 14 | /* var credentials = { 15 | user: process.env.C4S_USER, 16 | pass: process.env.C4S_PASS 17 | }; */ 18 | /* const wdioParams = { 19 | client: client, 20 | cookie: cookie 21 | }; */ 22 | // c4s.login(credentials, wdioParams, function(err, data) { 23 | params.client 24 | // .setCookie(cookie) 25 | .url('https://admin.clips4sale.com/sales-reports/index') 26 | .waitForVisible('table#sales-report-table', 9000) 27 | .executeAsync(function(query, cb) { 28 | var reqData = { 29 | s_year : query.s_year, 30 | s_month : query.s_month, 31 | s_day : query.s_day, 32 | e_year : query.e_year, 33 | e_month : query.e_month, 34 | e_day : query.e_day, 35 | report_type : query.report_type || "Detail1", // Detail1, sum, categoryGroupingReport, ClipsNeverSoldReport, tributes, refundsChargebacks 36 | stores : query.stores || "all", // all, clip, video, image 37 | action : query.action || "reports" 38 | }; 39 | $.ajax({ 40 | type: "POST", 41 | async: false, 42 | url: "https://admin.clips4sale.com/sales/json", 43 | data: reqData, 44 | success: function(res) { 45 | console.log(res); // Debug in browser 46 | cb(res); 47 | }, 48 | dataType: "json" 49 | }); 50 | }, query).then(function(output) { 51 | // console.log(output); // Debug 52 | reponse.data = output.value; 53 | console.log(reponse.data); 54 | }) 55 | // Success Callback 56 | .next(function() { 57 | params.client.end(); /** Ends browser session {@link editVid| read editVids docs} */ 58 | console.log('Done!'); 59 | console.log(JSON.stringify(reponse, null, 2)); 60 | return callback(null, reponse); 61 | }) 62 | 63 | // Global Error Callback 64 | .catch((e) => { 65 | console.log(e); 66 | params.client.end(); /** Ends browser session {@link editVid| read editVids docs} */ 67 | return callback(e, e); 68 | }); 69 | // }); 70 | } 71 | 72 | module.exports = { 73 | getReport: getReport 74 | }; 75 | -------------------------------------------------------------------------------- /api/routes/hotmovies/hotmoviesHelper.js: -------------------------------------------------------------------------------- 1 | var hyperquest = require('hyperquest'); 2 | var fs = require('fs'); 3 | var path = require('path'); 4 | var Client = require('ftp'); 5 | var Minio = require('minio'); 6 | const conf = require(path.join(process.env.APPDATA, "clipnuke", "config.json")); 7 | 8 | function upload(event, callback) { 9 | 10 | var dstFile = path.basename(event.url); 11 | 12 | console.log('File: ', dstFile) 13 | 14 | function search(nameKey, myArray) { 15 | for (var i = 0; i < myArray.length; i++) { 16 | if (myArray[i].name === nameKey) { 17 | return myArray[i]; 18 | } 19 | } 20 | } 21 | 22 | var ftpClient = new Client(); 23 | 24 | ftpClient.connect({ 25 | host: 'ftp.vod.com', 26 | user: conf.setting.hotmovies.user, 27 | password: conf.setting.hotmovies.pass 28 | }); 29 | 30 | ftpClient.on('ready', function() { 31 | 32 | /* var src = request({ 33 | url: event.url, 34 | method: "HEAD" 35 | }, function(err, response, body) { 36 | console.log(response.headers); 37 | return response.headers; 38 | // process.exit(0); 39 | }); */ 40 | // console.log(size); 41 | 42 | ftpClient.list('/', function(err, data) { 43 | // console.log(JSON.stringify(data, null, 2)); // Debug 44 | if (err) { 45 | console.log(err); 46 | } 47 | var obj = search(dstFile, data); 48 | console.log(obj); 49 | // console.log('File Size: ' + obj.size + ' Bytes'); 50 | // console.log(src, obj.size); 51 | 52 | if (obj) { 53 | ftpClient.end(); 54 | console.log('File already exists on destination server\'s filesystem.'); 55 | callback(null, obj); 56 | // process.exit(0); 57 | } else { 58 | 59 | if (event.type == "video") { 60 | 61 | // Allow insecure TLS connections 62 | process.env['NODE_TLS_REJECT_UNAUTHORIZED'] = '0'; 63 | 64 | // Setup minio client 65 | var minioClient = new Minio.Client({ 66 | endPoint: conf.setting.s3.endpoint, 67 | port: conf.setting.s3.port || 9000, 68 | useSSL: true, 69 | accessKey: conf.setting.s3.access_key, 70 | secretKey: conf.setting.s3.secret_key 71 | }); 72 | 73 | var size = 0; 74 | 75 | // Grab our video file from an s3-compatible server and stream (dataStream) 76 | minioClient.getObject('vods', event.url, function(err, dataStream) { 77 | if (err) { 78 | return console.log(err) 79 | } 80 | dataStream.on('data', function(chunk) { 81 | size += chunk.length 82 | }) 83 | dataStream.on('end', function() { 84 | console.log('End. Total size = ' + size) 85 | }) 86 | dataStream.on('error', function(err) { 87 | console.log(err) 88 | }) 89 | 90 | console.time("upload"); 91 | 92 | // Pipe stream to destination FTP server 93 | ftpClient.put(dataStream, dstFile, function(err) { 94 | if (err) { 95 | console.log(err); 96 | } 97 | ftpClient.end(); 98 | console.timeEnd("upload"); 99 | console.log("Finished"); 100 | }); 101 | }); 102 | } else { 103 | 104 | // Grab from HTTP request and stream 105 | var stream = hyperquest(event.url); 106 | console.time("upload"); 107 | 108 | // Pipe stream to destination FTP server 109 | ftpClient.put(stream, dstFile, function(err) { 110 | if (err) { 111 | console.log(err); 112 | } 113 | ftpClient.end(); 114 | console.timeEnd("upload"); 115 | console.log("Finished"); 116 | }); 117 | } 118 | } 119 | }); 120 | 121 | }); 122 | 123 | var upload = function() { 124 | ftpClient.size(dstFile, function(err, size) { 125 | // Assuming the err is the file not existing, good enough for now 126 | // err.code will give the exact status code otherwise (550 is file not found) 127 | var stream = hyperquest('event.url'); 128 | if (err) { 129 | 130 | hyperquest('event.url').pipe(res)(function(res) { 131 | // console.log(stream); 132 | ftpClient.put(stream, dstFile, function(err) { 133 | if (err) { 134 | console.log(err); 135 | } 136 | ftpClient.end(); 137 | console.timeEnd("upload"); 138 | console.log("Finished"); 139 | }); 140 | }); 141 | 142 | } else { 143 | 144 | console.log("Resuming download at start: " + size); 145 | getFileFromS3(size, function(res) { 146 | 147 | ftpClient.append(res, dstFile, function(err) { 148 | if (err) { 149 | console.log(err); 150 | } 151 | 152 | ftpClient.end(); 153 | console.timeEnd("upload"); 154 | console.log("Finished"); 155 | }); 156 | }); 157 | 158 | } 159 | }); 160 | }; 161 | 162 | ftpClient.on('close', function(hadError) { 163 | if (hadError) { 164 | console.log("FTP server closed with an error"); 165 | // callback("FTP server closed with an error"); 166 | } else { 167 | console.log("FTP server closed"); 168 | // done(); 169 | } 170 | }); 171 | 172 | ftpClient.on('error', function(err) { 173 | console.log("FTP server had error: " + err); 174 | }); 175 | 176 | 177 | ftpClient.on('end', function() { 178 | console.log("FTP server ended connection"); 179 | }); 180 | 181 | ftpClient.on('greeting', function(msg) { 182 | console.log(msg); 183 | }); 184 | 185 | } 186 | 187 | function httpUpload(event, callback) { 188 | 189 | var dstFile = path.basename(event.url); 190 | var ext = path.extname(event.url); 191 | var dstPath; 192 | if (ext == ".mp4" || ".wmv" || ".mov" || ".avi") { 193 | dstPath = '/clips'; 194 | } else if (ext == ".jpg" || ".gif" || ".png" || ".jpeg" || ".tiff" || ".tif") { 195 | dstPath = '/clip_images'; 196 | } 197 | switch (event.type) { 198 | case "trailer": 199 | dstPath = '/clips_previews'; 200 | break; 201 | case "video": 202 | dstPath = '/clips'; 203 | break; 204 | case "poster": 205 | dstPath = '/clip_images'; 206 | break; 207 | } 208 | console.log('File: ', dstFile) 209 | 210 | function search(nameKey, myArray) { 211 | for (var i = 0; i < myArray.length; i++) { 212 | if (myArray[i].name === nameKey) { 213 | return myArray[i]; 214 | } 215 | } 216 | } 217 | 218 | var ftpClient = new Client(); 219 | 220 | ftpClient.connect({ 221 | host: 'aebnftp.dataconversions.biz', 222 | user: event["credentials"][0]["user"] || process.env.AEBN_USER, 223 | password: event["credentials"][0]["pass"] || process.env.AEBN_PASS 224 | }); 225 | 226 | ftpClient.on('ready', function() { 227 | 228 | /** Change directory on FTP server */ 229 | ftpClient.cwd(dstPath, function(err, currentDir) { 230 | if (err) throw err; 231 | console.log(`Directory changed to ${dstPath}`); 232 | 233 | ftpClient.list(dstPath, function(err, data) { 234 | // console.log(JSON.stringify(data, null, 2)); // Debug 235 | if (err) { 236 | console.log(err); 237 | } 238 | var obj = search(dstFile, data); 239 | console.log(obj); 240 | // console.log('File Size: ' + obj.size + ' Bytes'); 241 | // console.log(src, obj.size); 242 | 243 | if (obj) { 244 | ftpClient.end(); 245 | console.log('File already exists on destination server\'s filesystem.'); 246 | callback(null, obj); 247 | // process.exit(0); 248 | } else { 249 | 250 | // Grab from HTTP request and stream 251 | var stream = hyperquest(event.url); 252 | console.time("upload"); 253 | 254 | // Pipe stream to destination FTP server 255 | ftpClient.put(stream, dstFile, function(err) { 256 | if (err) { 257 | console.log(err); 258 | } 259 | ftpClient.end(); 260 | console.timeEnd("upload"); 261 | console.log("Finished"); 262 | }); 263 | } 264 | }); 265 | }); 266 | }); 267 | 268 | var upload = function() { 269 | ftpClient.size(dstFile, function(err, size) { 270 | // Assuming the err is the file not existing, good enough for now 271 | // err.code will give the exact status code otherwise (550 is file not found) 272 | var stream = hyperquest('event.url'); 273 | if (err) { 274 | 275 | hyperquest('event.url').pipe(res)(function(res) { 276 | // console.log(stream); 277 | ftpClient.put(stream, dstFile, function(err) { 278 | if (err) { 279 | console.log(err); 280 | } 281 | ftpClient.end(); 282 | console.timeEnd("upload"); 283 | console.log("Finished"); 284 | }); 285 | }); 286 | 287 | } else { 288 | 289 | console.log("Resuming download at start: " + size); 290 | getFileFromS3(size, function(res) { 291 | 292 | ftpClient.append(res, dstFile, function(err) { 293 | if (err) { 294 | console.log(err); 295 | } 296 | 297 | ftpClient.end(); 298 | console.timeEnd("upload"); 299 | console.log("Finished"); 300 | }); 301 | }); 302 | 303 | } 304 | }); 305 | }; 306 | 307 | ftpClient.on('close', function(hadError) { 308 | if (hadError) { 309 | console.log("FTP server closed with an error"); 310 | // callback("FTP server closed with an error"); 311 | } else { 312 | console.log("FTP server closed"); 313 | // done(); 314 | } 315 | }); 316 | 317 | ftpClient.on('error', function(err) { 318 | console.log("FTP server had error: " + err); 319 | }); 320 | 321 | 322 | ftpClient.on('end', function() { 323 | console.log("FTP server ended connection"); 324 | }); 325 | 326 | ftpClient.on('greeting', function(msg) { 327 | console.log(msg); 328 | }); 329 | 330 | } 331 | 332 | module.exports = { 333 | upload: upload, 334 | httpUpload: httpUpload 335 | }; 336 | -------------------------------------------------------------------------------- /api/routes/hotmovies/index.js: -------------------------------------------------------------------------------- 1 | var hotmovies = require('express').Router({ 2 | mergeParams: true 3 | }); 4 | const path = require('path'); 5 | var bodyParser = require('body-parser') 6 | var jsonParser = bodyParser.json() 7 | 8 | // clips4sale Helper 9 | const hotmoviesHelper = require('./hotmoviesHelper.js'); 10 | 11 | const conf = require(path.join(process.env.APPDATA, "clipnuke", "config.json")); 12 | 13 | hotmovies.post('/', jsonParser, function(req, res) { 14 | var event = req.body; 15 | const credentials = { 16 | user: conf.settings.hotmovies.user, 17 | pass: conf.settings.hotmovies.pass 18 | }; 19 | // console.log(req, res); 20 | event.credentials = []; 21 | event.credentials.push(credentials); 22 | console.log(event); 23 | hotmoviesHelper.upload(req.body, function(err, data) { 24 | if (err) { 25 | callback(err, data); 26 | } else { 27 | console.log(data); 28 | res.status(200).json(data); 29 | } 30 | }); 31 | // console.log(req.body); // your JSON 32 | // res.send(req.body); // echo the result back 33 | }); 34 | 35 | module.exports = hotmovies; 36 | -------------------------------------------------------------------------------- /api/routes/index.js: -------------------------------------------------------------------------------- 1 | const router = require('express').Router({ mergeParams: true }); 2 | var manyvids = require('./manyvids'); 3 | var clips4sale = require('./clips4sale'); 4 | var xvideos = require('./xvideos'); 5 | // var google = require('./google'); 6 | var azure = require('./azure'); 7 | var clipnuke = require('./clipnuke'); 8 | var woo = require('./woo'); 9 | var pornhub = require('./pornhub'); 10 | var aebn = require('./aebn'); 11 | var hotmovies = require('./hotmovies'); 12 | var adultempire = require('./adultempire'); 13 | var local = require('./local'); 14 | 15 | /** 16 | * ManyVids Router 17 | * @type {String} 18 | */ 19 | router.use('/manyvids', manyvids); 20 | 21 | /** 22 | * Clips4Sale Router 23 | * @type {String} 24 | */ 25 | router.use('/clips4sale', clips4sale); 26 | 27 | /** 28 | * Xvideos Router 29 | * @type {String} 30 | */ 31 | router.use('/xvideos', xvideos); 32 | 33 | /** 34 | * Google Router 35 | * @type {String} 36 | */ 37 | // router.use('/google', google); 38 | 39 | /** 40 | * Azure Router 41 | * @type {String} 42 | */ 43 | router.use('/azure', azure); 44 | 45 | /** 46 | * Clipnuke Router 47 | * @type {String} 48 | */ 49 | router.use('/clipnuke', clipnuke); 50 | 51 | /** 52 | * WooCommerce Router 53 | * @type {String} 54 | */ 55 | router.use('/woo', woo); 56 | 57 | /** 58 | * Clipnuke Router 59 | * @type {String} 60 | */ 61 | router.use('/pornhub', pornhub); 62 | 63 | /** 64 | * Clipnuke Router 65 | * @type {String} 66 | */ 67 | router.use('/aebn', aebn); 68 | 69 | /** 70 | * Clipnuke Router 71 | * @type {String} 72 | */ 73 | router.use('/hotmovies', hotmovies); 74 | 75 | /** 76 | * Clipnuke Router 77 | * @type {String} 78 | */ 79 | router.use('/adultempire', adultempire); 80 | 81 | /** 82 | * Clipnuke Router 83 | * @type {String} 84 | */ 85 | router.use('/local', local); 86 | 87 | module.exports = router; 88 | -------------------------------------------------------------------------------- /api/routes/local/index.js: -------------------------------------------------------------------------------- 1 | const local = require('express').Router({ 2 | mergeParams: true 3 | }); 4 | const path = require('path'); 5 | const fs = require('fs'); 6 | const bodyParser = require('body-parser') 7 | const jsonParser = bodyParser.json() 8 | const conf = require(path.join(process.env.APPDATA, "clipnuke", "config.json")); 9 | const spawn = require('child_process').spawn; 10 | 11 | // clips4sale Helper 12 | // const localHelper = require(path.join(__dirname, 'localHelper.js')); 13 | 14 | // Test Route 15 | local.get('/', (req, res) => { 16 | res.status(200).json({ 17 | message: 'Local API' 18 | }); 19 | }); 20 | 21 | // List Clips 22 | local.get('/files', function(req, res) { 23 | // Where our files are stored 24 | const directoryPath = path.join(conf.settings.local.dir.videos || "%USERPROFILE%/Videos"); // TODO change to var 25 | //passsing directoryPath and callback function 26 | fs.readdir(directoryPath, function(err, files) { 27 | //handling error 28 | if (err) { 29 | return console.log('Unable to scan directory: ' + err); 30 | } 31 | var arr = []; 32 | var itemsProcessed = 0; 33 | 34 | function callback() { 35 | res.status(200).json({ 36 | files: arr 37 | }); 38 | console.log('all done'); 39 | } 40 | //listing all files using forEach 41 | files.forEach(function(file, index, array) { 42 | // Do whatever you want to do with the file 43 | arr.push(file); 44 | console.log(file); 45 | itemsProcessed++; 46 | if (itemsProcessed === array.length) { 47 | callback(); 48 | } 49 | }, arr); 50 | }, res); 51 | }); 52 | 53 | // List Clips 54 | local.post('/ffmpeg/transcode', jsonParser, function(req, res) { 55 | const event = req.body; 56 | const input = event.input; 57 | var input_path = path.dirname(input); 58 | var basename = path.basename(input, ".mxf"); 59 | const ext = path.extname(input); 60 | // const path = path.parse(event.input); 61 | // const filename = req.body.input; 62 | var cmd = ""; 63 | const child1 = spawn('ffmpeg', ['-i', `${input}`, '-i', conf.settings.ffmpeg.watermark.hd, '-filter_complex', '[0:v]scale=1920:1080[scaled];[scaled][1:v]overlay=0:0', '-c:v', 'h264_nvenc', '-profile:v', 'main', '-level:v', '4.1', '-c:a', 'copy', '-acodec', 'aac', '-ab', '128k', '-b:v', '6000k', `${input_path}/${basename}_hd.mp4`]); 64 | const child2 = spawn('ffmpeg', ['-i', `${input}`, '-i', conf.settings.ffmpeg.watermark.sd.mp4, '-filter_complex', '[0:v]scale=720:480[scaled];[scaled][1:v]overlay=0:0', '-c:v', 'h264_nvenc', '-profile:v', 'main', '-level:v', '3.0', '-c:a', 'copy', '-acodec', 'aac', '-ab', '128k', '-b:v', '2500k', `${input_path}/${basename}_sd.mp4`]); 65 | const child3 = spawn('ffmpeg', ['-i', `${input}`, '-i', conf.settings.ffmpeg.watermark.hd, '-filter_complex', '[0:v]scale=1920:1080[scaled];[scaled][1:v]overlay=0:0', '-b', '6000k', '-vcodec', 'wmv2', '-acodec', 'wmav2', `${input_path}/${basename}_hd.wmv`]); 66 | const child4 = spawn('ffmpeg', ['-i', `${input}`, '-i', conf.settings.ffmpeg.watermark.sd.wmv, '-filter_complex', '[0:v]scale=854:480[scaled];[scaled][1:v]overlay=0:0', '-b', '2000k', '-vcodec', 'wmv2', '-acodec', 'wmav2', `${input_path}/${basename}_sd.wmv`]); 67 | child1.on('exit', (code) => { 68 | console.log(`Child process exited with code ${code}`); 69 | if (code === 0) { 70 | res.status(200).json({ 71 | message: 'FFMpeg/transcode ran successfully.' 72 | }); 73 | } else { 74 | res.status(200).json({ 75 | message: `Error Code ${code}`, 76 | code: code 77 | }); 78 | } 79 | }); 80 | child1.stdout.on('data', (data) => { 81 | console.log(`stdout: ${data}`); 82 | // res.status(200).json(data); 83 | }); 84 | child1.stderr.on('data', (data) => { 85 | console.log(`stderr: ${data}`); 86 | // res.status(400).json(data); 87 | }); 88 | }); 89 | 90 | module.exports = local; 91 | -------------------------------------------------------------------------------- /api/routes/manyvids/cookie.json: -------------------------------------------------------------------------------- 1 | { 2 | "domain":".manyvids.com", 3 | "expiry":1520927551.376236, 4 | "httpOnly":true, 5 | "name":"PHPSESSID", 6 | "path":"/", 7 | "secure":false, 8 | "value":"rb1kb7j0t2k1pbja6agg8trkd1" 9 | } 10 | -------------------------------------------------------------------------------- /api/routes/manyvids/index.js: -------------------------------------------------------------------------------- 1 | var manyvids = require('express').Router({ 2 | mergeParams: true 3 | }); 4 | const path = require('path'); 5 | const spawn = require('child_process').spawn; // TODO Change to fork 6 | var bodyParser = require('body-parser'); 7 | var jsonParser = bodyParser.json(); 8 | 9 | // ManyVids Helper 10 | const mv = require('./mvHelper.js'); 11 | 12 | // Webdriver Client Instance 13 | const client = require('../../webdriverio/client.js').client; 14 | const conf = require(path.join(process.env.APPDATA, "clipnuke", "config.json")); 15 | 16 | // Test cookie - Pre-authenticated 17 | // const cookie = require('./cookie.json'); // for advanced auth only 18 | 19 | /** 20 | * Test Route - Root 21 | * @type {String} 22 | */ 23 | manyvids.get('/', (req, res) => { 24 | res.status(200).json({ 25 | message: 'ManyVids Router!' 26 | }); 27 | }); 28 | 29 | // route to trigger the capture 30 | manyvids.get('/vids', function(req, res) { 31 | var id = req.params.id; 32 | console.log(`GET /vids - Mock Endpoint`); // Mock 33 | res.json({}); 34 | }); 35 | 36 | // route to trigger the capture 37 | manyvids.get('/vids/:id', function(req, res) { 38 | var id = req.params.id; 39 | console.log(`Requesting Clip ID: ${id}`); 40 | // res.json({id}); 41 | 42 | var credentials = { 43 | user: conf.settings.manyvids.user, 44 | pass: conf.settings.manyvids.pass 45 | }; 46 | 47 | const params = { 48 | client: client, 49 | // cookie: cookie // For advanced cases 50 | }; 51 | 52 | mv.login(credentials, params, function(err, data) { 53 | 54 | mv.getVid(id, params, function(err, data) { 55 | console.log(data); 56 | res.json(data); 57 | }); 58 | 59 | }); 60 | 61 | }); 62 | 63 | // route to trigger the capture 64 | manyvids.post('/vids', jsonParser, function(req, res) { 65 | const event = req.body; 66 | const credentials = { 67 | user: conf.settings.manyvids.user, 68 | pass: conf.settings.manyvids.pass 69 | }; 70 | const params = { 71 | client: client, 72 | cookie: { 73 | "domain": ".manyvids.com", 74 | "httpOnly": true, 75 | "name": "PHPSESSID", 76 | "path": "/", 77 | "secure": false, 78 | "value": conf.settings.manyvids.phpsessid 79 | } 80 | }; 81 | 82 | // mv.login(credentials, params, function(err, data) { 83 | 84 | mv.uploadVid(event, credentials, params, function(err, data) { 85 | if (err) { 86 | console.log(err); 87 | } 88 | console.log(data); 89 | res.json(data); 90 | }); 91 | 92 | // }); 93 | 94 | }); 95 | 96 | manyvids.post('/spawn', jsonParser, (req, res) => { 97 | const event = req.body; 98 | let child = spawn( 99 | 'node', 100 | [ 101 | path.join(__dirname, 'postVid.js'), 102 | JSON.stringify(event) 103 | ] 104 | ); 105 | child.on('exit', (code) => { 106 | console.log(`Child process exited with code ${code}`); 107 | if (code === 0) { 108 | res.status(200).json({ 109 | message: 'WebDriverIO ran successfully.' 110 | }); 111 | } 112 | }); 113 | child.stdout.on('data', (data) => { 114 | console.log(`stdout: ${data}`); 115 | // res.status(200).json(data); 116 | }); 117 | child.stderr.on('data', (data) => { 118 | console.log(`stderr: ${data}`); 119 | // res.status(400).json(data); 120 | }); 121 | }); 122 | 123 | manyvids.put('/spawn', jsonParser, (req, res) => { 124 | const event = req.body; 125 | let child = spawn( 126 | 'node', 127 | [ 128 | path.join(__dirname, 'putVid.js'), 129 | JSON.stringify(event) 130 | ] 131 | ); 132 | child.on('exit', (code) => { 133 | console.log(`Child process exited with code ${code}`); 134 | if (code === 0) { 135 | res.status(200).json({ 136 | message: 'WebDriverIO ran successfully.' 137 | }); 138 | } 139 | }); 140 | child.stdout.on('data', (data) => { 141 | console.log(`stdout: ${data}`); 142 | // res.status(200).json(data); 143 | }); 144 | child.stderr.on('data', (data) => { 145 | console.log(`stderr: ${data}`); 146 | // res.status(400).json(data); 147 | }); 148 | }); 149 | 150 | // route to trigger the capture 151 | manyvids.put('/vids/:id', jsonParser, function(req, res) { 152 | var id = req.params.id; 153 | console.log(`PUT /vids/${id} - Mock Endpoint`); // Mock 154 | console.log(req.header('X-Cookie')); // Mock 155 | const event = req.body; 156 | const credentials = { 157 | user: conf.settings.manyvids.user, 158 | pass: conf.settings.manyvids.pass 159 | }; 160 | const params = { 161 | client: client, 162 | cookie: { 163 | "domain": ".manyvids.com", 164 | "httpOnly": true, 165 | "name": "PHPSESSID", 166 | "path": "/", 167 | "secure": false, 168 | "value": req.header('X-Cookie') 169 | } 170 | }; 171 | 172 | // mv.login(credentials, params, function(err, data) { 173 | mv.login(credentials, params, function(err, data) { 174 | mv.postVid(id, event, params, function(err, data) { 175 | console.log(data); 176 | res.json(data); 177 | }); 178 | }); 179 | }); 180 | 181 | // route to trigger the capture 182 | manyvids.delete('/vids/:id', function(req, res) { 183 | var id = req.params.id; 184 | console.log(`DELETE /vids/${id} - Mock Endpoint`); // Mock 185 | res.json({}); 186 | }); 187 | 188 | module.exports = manyvids; 189 | -------------------------------------------------------------------------------- /api/routes/manyvids/mvHelper.js: -------------------------------------------------------------------------------- 1 | const webdriverio = require('webdriverio'); 2 | const path = require('path'); 3 | 4 | /** 5 | * Initialized a new WebDriverIO Client. 6 | */ 7 | const config = require(path.join(__dirname, '..', '..', 'webdriverio/config.js')).config; 8 | var client = webdriverio.remote(config); 9 | 10 | /** 11 | * Login to ManyVids. 12 | * Init a new webdriverio session. 13 | * @param {webdriverio} client A webdriverio client 14 | * @param {Function} callback err, data 15 | * @return {Object} A webdriverio cookie containing the authenticated PHPSESSID 16 | */ 17 | function auth(credentials, params, callback) { 18 | params.client 19 | .init().catch(function(err, params) { 20 | params.client.end(); /** Ends browser session {@link editVid| read editVids docs} */ 21 | console.log('WDIO.init() failed.'); 22 | return callback(`WDIO.init() failed.`, {}); 23 | }, params) 24 | // .setCookie(params.cookie) 25 | .url('https://www.manyvids.com/Login/') 26 | // .waitForVisible('button.js-warning18-popup', 3000) // No longer pops up on manyvids login page 27 | // .click('button.js-warning18-popup') 28 | .setValue('#triggerUsername', credentials.user) 29 | .setValue('#triggerPassword', credentials.pass) 30 | .waitForVisible('body > div.mv-profile', 30000) 31 | // .click('#loginAccountSubmit') 32 | // .pause(15000) // Wait in case we need to solve a recaptcha. 33 | .next(function(data) { 34 | console.log(data); 35 | return callback(null, data); 36 | }).catch((e) => console.log(e)); 37 | }; 38 | 39 | /** 40 | * Edit Vid - Details 41 | * Sends a GET request to the server, using an authenticated webdriverio session, fetches the data, then ends the session. 42 | * NOTE: It's super important to use .end() method to end the browser session. Because {@link auth | auth} calls init() to open a new browser session. 43 | * IMPORTANT: If we don't run browser.end(), this app will fail when {@link getVid | getVid} or another method is called! 44 | * @param {Integer} id A ManyVids Video ID 45 | * @param {Object} params client, cookie 46 | * @param {Function} callback [description] 47 | * @return {Object} An object containing details about a ManyVids video. 48 | */ 49 | function getVid(id, params, callback) { 50 | var data = {}; 51 | data.video = {}; 52 | data.website = "MANYVIDS"; 53 | data.categories = []; 54 | console.log(id, params); 55 | 56 | params.client 57 | .setCookie(params.cookie) 58 | .url(`https://www.manyvids.com/Edit-vid/${id}/`) 59 | .pause(2000) 60 | 61 | // Manyvids Session Details 62 | .getAttribute('html', 'data-session-details').then(function(val) { 63 | console.log('Session Details: ' + JSON.stringify(val)); 64 | data.session = JSON.parse(val); 65 | data.remoteStudioId = data.session.user_id; 66 | }) 67 | 68 | // ManyVids Video ID 69 | .getAttribute('body', 'data-video-id').then(function(val) { 70 | console.log('Video ID: ' + JSON.stringify(val)); 71 | data.video.id = val; 72 | data.remoteId = data.video.id; 73 | }) 74 | 75 | /** Local Error Callback 76 | * @todo Break on various errors 77 | * @return error message, {} 78 | */ 79 | .catch(function(err) { 80 | params.client.end(); /** Ends browser session {@link editVid| read editVids docs} */ 81 | console.log('Local catch called'); 82 | return callback(`Video ID not found for user ${data.session.username}. Error fetching the vid details.`, {}); 83 | }) 84 | 85 | // AWS eTag 86 | .getAttribute('body', 'data-etag').then(function(val) { 87 | console.log('eTag: ' + JSON.stringify(val)); 88 | data.video.etag = val; 89 | }) 90 | 91 | // Trailer Filename 92 | .getAttribute('body', 'data-filename').then(function(val) { 93 | console.log('Filename: ' + JSON.stringify(val)); 94 | data.video.filename = val; 95 | }) 96 | 97 | // Price 98 | .getValue('[name="video_cost"]').then(function(val) { 99 | console.log('Price is: ' + JSON.stringify(val * 1)); 100 | data.price = val * 1; 101 | }).catch(function(err) { 102 | params.client.end(); /** Ends browser session {@link editVid| read editVids docs} */ 103 | console.log('Local catch called'); 104 | return callback(`Video Cost not found for vid ID: ${id}. Error fetching the vid details.`, {}); 105 | }) 106 | 107 | 108 | // Video Title 109 | .getValue('[name="video_title"]').then(function(val) { 110 | console.log('Title is: ' + JSON.stringify(val)); 111 | data.name = val; 112 | }) 113 | 114 | // Description 115 | .getText('[name="video_description"]').then(function(val) { 116 | console.log('Title is: ' + JSON.stringify(val)); 117 | data.description = val; 118 | }) 119 | 120 | // Categories/"Tags" 121 | .getAttribute('//*[@id="videoSettings"]/div[1]/div/ul/li[1]/input', 'value').then(function(val) { 122 | if (val) { 123 | data.categories.push(val); 124 | } 125 | }) 126 | .getAttribute('//*[@id="videoSettings"]/div[1]/div/ul/li[2]/input', 'value').then(function(val) { 127 | if (val) { 128 | data.categories.push(val); 129 | } 130 | }) 131 | .getAttribute('//*[@id="videoSettings"]/div[1]/div/ul/li[3]/input', 'value').then(function(val) { 132 | if (val) { 133 | data.categories.push(val); 134 | } 135 | }) 136 | .getAttribute('//*[@id="videoSettings"]/div[1]/div/ul/li[4]/input', 'value').then(function(val) { 137 | if (val) { 138 | data.categories.push(val); 139 | } 140 | }) 141 | .getAttribute('//*[@id="videoSettings"]/div[1]/div/ul/li[5]/input', 'value').then(function(val) { 142 | if (val) { 143 | data.categories.push(val); 144 | } 145 | }) 146 | 147 | // Video Length 148 | .getAttribute('.js-video-length', 'data-video-length').then(function(val) { 149 | console.log(val); 150 | if (val * 1) { 151 | data.lengthSeconds = val * 1; 152 | } else { 153 | data.length = val; 154 | } 155 | }) 156 | 157 | // Intensity 158 | .execute(function(obj) { 159 | obj = jQuery('#intensity > option:selected')[0].value; 160 | return obj; 161 | }, data).then(function(obj) { 162 | console.log("Intensity", obj.value); 163 | data.intensity = obj.value; 164 | }) 165 | 166 | // Sale/Discount % 167 | .execute(function(obj) { 168 | obj = jQuery('#sale > option:selected')[0].value; 169 | return obj; 170 | }, data).then(function(obj) { 171 | var discount = obj.value; 172 | console.log(`Discount ${discount}`); 173 | data.discount = discount; 174 | if (discount) { 175 | data.salePrice = data.price - ((discount / 100) * data.price); 176 | } 177 | }) 178 | 179 | // Trailer URL 180 | .getAttribute('//*[@id="rmpPlayer"]', 'data-video-screenshot').then(function(val) { 181 | data.poster = val; 182 | }) 183 | 184 | // Poster Img URL 185 | .getAttribute('//*[@id="rmpPlayer"]', 'data-video-filepath').then(function(val) { 186 | data.trailer = val; 187 | }) 188 | 189 | /** CreatedAt Timestamp 190 | * Epoch milliseconds to UTC string 191 | */ 192 | .getAttribute('//*[@id="rmpPlayer"]', 'data-video-filepath').then(function(val) { 193 | var epochMs = 0; 194 | var d = new Date(0); // The 0 there is the key, which sets the date to the epoch 195 | // var val = "https://dntgjk0do84uu.cloudfront.net/364438/e1a1813a9e1abe9866c0b74118081a58/preview/1520188436784.mp4_480_1520188447.m3u8"; // test string 196 | var regex = /https:\/\/.*\/.*\/(\d{13}).mp4_\d{3,4}_\d{10}.m3u8/; // Regex search string 197 | var regex2 = /https:\/\/s3.amazonaws.com\/manyvids-data\/php_uploads\/preview_videos\/.*\/(\d{13})_preview.mp4/; // Regex search string 198 | 199 | if (regex.test(val)) { 200 | var match = regex.exec(val); 201 | epochMs = match[1]; 202 | } else if (regex2.test(val)) { 203 | var match = regex2.exec(val); 204 | epochMs = match[1]; 205 | } 206 | 207 | // console.log(match, epochMs); 208 | // console.log("Converting to UTC String"); 209 | d.setUTCMilliseconds(epochMs); // set the dat obj to the video creatiume time in epoch ms 210 | data.createdAt = d.toISOString(); // Convert to UTC timestamp 211 | }) 212 | 213 | // Success Callback 214 | .next(function() { 215 | params.client.end(); /** Ends browser session {@link editVid| read editVids docs} */ 216 | console.log('Done!'); 217 | console.log(JSON.stringify(data, null, 2)); 218 | return callback(null, data); 219 | }) 220 | 221 | // Global Error Callback 222 | .catch((e) => { 223 | console.log(e); 224 | params.client.end(); /** Ends browser session {@link editVid| read editVids docs} */ 225 | return callback(e, {}); 226 | }); 227 | }; 228 | 229 | /** 230 | * Put Vid - Details 231 | * @param {Integer} id A ManyVids Video ID 232 | * @param {Object} params client, cookie 233 | * @param {Function} callback [description] 234 | * @return {Object} An object containing details about a ManyVids video. 235 | */ 236 | function postVid(id, data, params, callback) { 237 | // var data = {}; 238 | // data.video = {}; 239 | // data.website = "MANYVIDS"; 240 | // data.categories = []; 241 | console.log(id, data, params); 242 | var localPath = 'X:\\S3Gateway\\NeroMedia\\xxxmultimedia-downloads\\' + data.filename; 243 | 244 | params.client 245 | // .setCookie(params.cookie) 246 | .waitForVisible('body > div.mv-profile', 30000) 247 | .url(`https://www.manyvids.com/Edit-vid/${id}/`) 248 | .chooseFile(selector, localPath) 249 | .url(`https://www.manyvids.com/Edit-vid/${id}/`) 250 | .pause(2000) 251 | // Manyvids Session Details 252 | .getAttribute('html', 'data-session-details').then(function(val) { 253 | console.log('Session Details: ' + JSON.stringify(val)); 254 | data.session = JSON.parse(val); 255 | data.remoteStudioId = data.session.user_id; 256 | }) 257 | 258 | // ManyVids Video ID 259 | .getAttribute('body', 'data-video-id').then(function(val) { 260 | console.log('Video ID: ' + JSON.stringify(val)); 261 | data.video.id = val; 262 | data.remoteId = data.video.id; 263 | }) 264 | 265 | // AWS eTag 266 | .getAttribute('body', 'data-etag').then(function(val) { 267 | console.log('eTag: ' + JSON.stringify(val)); 268 | data.video.etag = val; 269 | }) 270 | 271 | // Trailer Filename 272 | .getAttribute('body', 'data-filename').then(function(val) { 273 | console.log('Filename: ' + JSON.stringify(val)); 274 | data.video.filename = val; 275 | }) 276 | 277 | // Price 278 | .getValue('[name="video_cost"]').then(function(val) { 279 | console.log('Price is: ' + JSON.stringify(val * 1)); 280 | data.price = val * 1; 281 | }) 282 | 283 | // Video Title 284 | .getValue('[name="video_title"]').then(function(val) { 285 | console.log('Title is: ' + JSON.stringify(val)); 286 | data.name = val; 287 | }) 288 | 289 | // Description 290 | .getText('[name="video_description"]').then(function(val) { 291 | console.log('Title is: ' + JSON.stringify(val)); 292 | data.description = val; 293 | }) 294 | 295 | // Categories/"Tags" 296 | .getAttribute('//*[@id="videoSettings"]/div[1]/div/ul/li[1]/input', 'value').then(function(val) { 297 | if (val) { 298 | data.categories.push(val); 299 | } 300 | }) 301 | .getAttribute('//*[@id="videoSettings"]/div[1]/div/ul/li[2]/input', 'value').then(function(val) { 302 | if (val) { 303 | data.categories.push(val); 304 | } 305 | }) 306 | .getAttribute('//*[@id="videoSettings"]/div[1]/div/ul/li[3]/input', 'value').then(function(val) { 307 | if (val) { 308 | data.categories.push(val); 309 | } 310 | }) 311 | .getAttribute('//*[@id="videoSettings"]/div[1]/div/ul/li[4]/input', 'value').then(function(val) { 312 | if (val) { 313 | data.categories.push(val); 314 | } 315 | }) 316 | .getAttribute('//*[@id="videoSettings"]/div[1]/div/ul/li[5]/input', 'value').then(function(val) { 317 | if (val) { 318 | data.categories.push(val); 319 | } 320 | }) 321 | 322 | // Video Length 323 | .getAttribute('.js-video-length', 'data-video-length').then(function(val) { 324 | console.log(val); 325 | if (val * 1) { 326 | data.lengthSeconds = val * 1; 327 | } else { 328 | data.length = val; 329 | } 330 | }) 331 | 332 | // Intensity 333 | .execute(function(obj) { 334 | obj = jQuery('#intensity > option:selected')[0].value; 335 | return obj; 336 | }, data).then(function(obj) { 337 | console.log("Intensity", obj.value); 338 | data.intensity = obj.value; 339 | }) 340 | 341 | /** Local Error Callback 342 | * @todo Break on various errors 343 | * @return error message, {} 344 | */ 345 | .catch(function(err) { 346 | console.log('Local catch called'); 347 | return callback("Error fetching the vid details.", {}); 348 | }) 349 | 350 | // Sale/Discount % 351 | .execute(function(obj) { 352 | obj = jQuery('#sale > option:selected')[0].value; 353 | return obj; 354 | }, data).then(function(obj) { 355 | var discount = obj.value; 356 | console.log(`Discount ${discount}`); 357 | data.discount = discount; 358 | if (discount) { 359 | data.salePrice = data.price - ((discount / 100) * data.price); 360 | } 361 | }) 362 | 363 | // Trailer URL 364 | .getAttribute('//*[@id="rmpPlayer"]', 'data-video-filepath').then(function(val) { 365 | data.poster = val; 366 | }) 367 | 368 | // Poster Img URL 369 | .getAttribute('//*[@id="rmpPlayer"]', 'data-video-screenshot').then(function(val) { 370 | data.trailer = val; 371 | }) 372 | 373 | /** CreatedAt Timestamp 374 | * Epoch milliseconds to UTC string 375 | */ 376 | .getAttribute('//*[@id="rmpPlayer"]', 'data-video-filepath').then(function(val) { 377 | var epochMs = 0; 378 | var d = new Date(0); // The 0 there is the key, which sets the date to the epoch 379 | // var val = "https://dntgjk0do84uu.cloudfront.net/364438/e1a1813a9e1abe9866c0b74118081a58/preview/1520188436784.mp4_480_1520188447.m3u8"; // test string 380 | var regex = /https:\/\/.*\/.*\/(\d{13}).mp4_\d{3,4}_\d{10}.m3u8/; // Regex search string 381 | var regex2 = /https:\/\/s3.amazonaws.com\/manyvids-data\/php_uploads\/preview_videos\/.*\/(\d{13})_preview.mp4/; // Regex search string 382 | 383 | if (regex.test(val)) { 384 | var match = regex.exec(val); 385 | epochMs = match[1]; 386 | } else if (regex2.test(val)) { 387 | var match = regex2.exec(val); 388 | epochMs = match[1]; 389 | } 390 | 391 | // console.log(match, epochMs); 392 | // console.log("Converting to UTC String"); 393 | d.setUTCMilliseconds(epochMs); // set the dat obj to the video creatiume time in epoch ms 394 | data.createdAt = d.toISOString(); // Convert to UTC timestamp 395 | }) 396 | 397 | // Success Callback 398 | .next(function() { 399 | params.client.end(); 400 | console.log('Done!'); 401 | console.log(JSON.stringify(data, null, 2)); 402 | return callback(null, data); 403 | }) 404 | 405 | // Global Error Callback 406 | .catch((e) => console.log(e)); 407 | }; 408 | 409 | function uploadVid(event, credentials, params, callback) { 410 | // var localPath = 'X:\\S3Gateway\\NeroMedia\\xxxmultimedia-downloads\\' + event.filename; 411 | var uploadCount; 412 | console.log(params); 413 | client 414 | .init().catch(function(err, params) { 415 | params.client.end(); 416 | console.log('WDIO.init() failed.'); 417 | return callback(`WDIO.init() failed.`, {}); 418 | }, params) 419 | 420 | // Login and wait for user to click submit 421 | .url('https://www.manyvids.com/Login/') 422 | .setValue('#triggerUsername', credentials.user) 423 | .setValue('#triggerPassword', credentials.pass) 424 | .waitForVisible('body > div.mv-profile', 60000) 425 | 426 | // Upload the file. 427 | .url(`https://www.manyvids.com/Upload-vids/`) 428 | .waitForVisible('#pickfiles', 30000) 429 | .execute(function(uploadCount) { 430 | uploadCount = $("div.action-link > a").length; 431 | }, uploadCount) 432 | .click('#pickfiles') 433 | // .chooseFile(`input[type="file"][0]`,localPath) 434 | 435 | // Wait for the Edit Page, then prefill 436 | .waitForVisible("li.js-upload-row > div > div > div > h5", 180000) 437 | // .execute(function(description) { 438 | // "https://manyvids.com/" + $("div.action-link > a").attr("href"); 439 | // }) 440 | .waitUntil(() => { 441 | console.log("i.processing-upload-icon"); 442 | return $("i.processing-upload-icon").length === 0 443 | }, 5000, 'expected text to be different after 5s') 444 | .execute(function() { 445 | UploadComplete 446 | }) 447 | // .waitForVisible("body > div.mv-controls > div.video-player-edit-page", 1800000) 448 | .setValue('[name="video_title"]', event.name) 449 | .setValue('[name="video_description"]', event.description) 450 | // .pause(2000) 451 | // .chooseFile("#container > div > input", file) 452 | .getValue("#container > div > input").then(function(val) { 453 | console.log('File to Upload: ' + JSON.stringify(val)); 454 | }); 455 | } 456 | 457 | module.exports = { 458 | login: auth, 459 | editVid: getVid, 460 | uploadVid: uploadVid, 461 | postVid: postVid 462 | }; 463 | -------------------------------------------------------------------------------- /api/routes/manyvids/postVid.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs'); 2 | const path = require('path'); 3 | const webdriverio = require('webdriverio'); 4 | 5 | // Webdriver Client Instance 6 | var config = { 7 | desiredCapabilities: { 8 | browserName: 'chrome', 9 | chromeOptions: { 10 | binary: path.join(__dirname, '../../../../bin/chromedriver.exe') 11 | }, 12 | }, 13 | singleton: true, // Enable persistent sessions 14 | debug: true, 15 | // host: "http://127.0.0.1", 16 | // port: 4444 17 | }; 18 | var client = webdriverio.remote(config); 19 | const conf = require(path.join(process.env.APPDATA, "clipnuke", "config.json")) 20 | var event = JSON.parse(process.argv[2]); 21 | var uploadCount = 0; 22 | 23 | client 24 | .init().catch(function(err, params) { 25 | client.end(); /** Ends browser session {@link editVid| read editVids docs} */ 26 | console.log('WDIO.init() failed.'); 27 | return callback(`WDIO.init() failed.`, {}); 28 | }) 29 | // .setCookie(cookie) 30 | .url('https://www.manyvids.com/Login/') 31 | // .waitForVisible('button.js-warning18-popup', 3000) // No longer pops up on manyvids login page 32 | // .click('button.js-warning18-popup') 33 | .setValue('#triggerUsername', conf.settings.manyvids.user) 34 | .setValue('#triggerPassword', conf.settings.manyvids.pass) 35 | .waitForVisible('body > div.mv-profile', 30000) 36 | // .click('#loginAccountSubmit') 37 | 38 | // Upload the file. 39 | .url(`https://www.manyvids.com/Upload-vids/`) 40 | .waitForVisible('#pickfiles', 30000) 41 | .execute(function(uploadCount) { 42 | uploadCount = $("div.action-link > a").length; 43 | }, uploadCount) 44 | .click('#pickfiles') 45 | // .chooseFile(`input[type="file"][0]`,localPath) 46 | 47 | // Wait for the Edit Page, then prefill 48 | .waitForVisible("li.js-upload-row > div > div > div > h5", 180000) 49 | // .execute(function(description) { 50 | // "https://manyvids.com/" + $("div.action-link > a").attr("href"); 51 | // }) 52 | .waitUntil(() => { 53 | console.log("i.processing-upload-icon"); 54 | return $("i.processing-upload-icon").length === 0 55 | }, 5000, 'expected text to be different after 5s') 56 | .execute(function() { 57 | UploadComplete 58 | }) 59 | // .waitForVisible("body > div.mv-controls > div.video-player-edit-page", 1800000) 60 | .setValue('[name="video_title"]', event.name) 61 | .setValue('[name="video_description"]', event.description) 62 | // .pause(2000) 63 | // .chooseFile("#container > div > input", file) 64 | .getValue("#container > div > input").then(function(val) { 65 | console.log('File to Upload: ' + JSON.stringify(val)); 66 | }); 67 | -------------------------------------------------------------------------------- /api/routes/manyvids/putVid.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs'); 2 | const path = require('path'); 3 | const webdriverio = require('webdriverio'); 4 | 5 | // Webdriver Client Instance 6 | var config = { 7 | desiredCapabilities: { 8 | browserName: 'chrome', 9 | chromeOptions: { 10 | binary: path.join(__dirname, '../../../../bin/chromedriver.exe') 11 | }, 12 | }, 13 | singleton: true, // Enable persistent sessions 14 | debug: true 15 | }; 16 | var client = webdriverio.remote(config); 17 | const conf = require(path.join(process.env.APPDATA, "clipnuke", "config.json")) 18 | var event = JSON.parse(process.argv[2]); 19 | 20 | client 21 | .init() 22 | .url('https://www.manyvids.com/Login/') 23 | .setValue('#triggerUsername', conf.settings.manyvids.user) 24 | .setValue('#triggerPassword', conf.settings.manyvids.pass) 25 | .waitForVisible('body > div.mv-profile', 30000) 26 | .pause(2000) 27 | .url(`https://www.manyvids.com/Edit-vid/${event.manyvids_id}/`) 28 | .waitForVisible('input#Title', 60000) 29 | .execute(function(event) { 30 | $(document).ready(function() { 31 | // Title 32 | $('[name="video_title"]').val(event.name); 33 | // Description 34 | $('[name="video_description"]').val(event.description.replace(/(<([^>]+)>)/ig, "")); // Strip HTML tags 35 | 36 | // Teaser 37 | // Thumbnail 38 | 39 | // Categories 40 | if ($('ul.multi-dropdown-list').length) { 41 | $('ul.multi-dropdown-list').html(''); // Clear list 42 | } 43 | event.categories.forEach(function(value, index){ 44 | $('ul.multi-dropdown-list').append(`
  • xCAT # ${value}
  • `); 45 | }); 46 | 47 | // "Set Your Price" - Default 48 | // TODO: Set price by video length 49 | $("#free_vid_0").click(); 50 | $('[name="video_cost"]').val(event.price || 9.99); 51 | 52 | // "MV Tube" 53 | if (event.tube) { 54 | $("#free_vid_1").click(); 55 | $("#appendedPrependedDownloadCost").val(event.price || 4.99); // Download price 56 | } 57 | 58 | // "Make This Vid Free" 59 | if (event.free) { 60 | $("#free_vid_2").click(); 61 | } 62 | 63 | // Intensity 64 | $('#intensity').val(event.intensity || 0); 65 | $('#intensity').niceSelect('update'); 66 | 67 | // Discount 68 | $("#sale").val(event.discountPercentage || ""); 69 | $("#sale").niceSelect('update'); 70 | 71 | // Exclusive? 72 | $("#exclusiveVid").prop("checked", event.exclusive || false); 73 | 74 | // Model Attributes 75 | $("#age_basic").val(event.age || false); 76 | $("#age_basic").niceSelect('update'); 77 | $("#ethnicity_basic").val(event.ethnicity || false); 78 | $("#ethnicity_basic").niceSelect('update'); 79 | $("#breast_size_basic").val(event.breastSize || false); 80 | $("#breast_size_basic").niceSelect('update'); 81 | 82 | // Custom Vid Order? 83 | $("#show_customvid_table").prop("checked", event.custom || false); 84 | 85 | // Security Options 86 | $("#stream_only").val(event.streamOnly || 1); 87 | $("#stream_only").niceSelect("update"); 88 | 89 | // Block Teaser 90 | $("#block_preview").prop("checked", event.blockPreview || false); 91 | 92 | // Content Rating 93 | if (event.sfw === true || event.nsfw === false) { 94 | $("#safe_for_work").val(1199); // SFW 95 | } else { 96 | $("#safe_for_work").val(); // NSFW (Default) 97 | } 98 | $("#safe_for_work").niceSelect('update'); 99 | }); 100 | }, event) 101 | 102 | .catch((e) => { 103 | client.end(); 104 | console.log(e); 105 | // return callback(e); 106 | }); 107 | -------------------------------------------------------------------------------- /api/routes/woo/client.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const WooCommerceAPI = require('woocommerce-api'); 4 | 5 | /** Setup WooCommerce client */ 6 | var WooCommerce = new WooCommerceAPI({ 7 | url: process.env.WP_BASE_URL, 8 | consumerKey: process.env.WC_CONSUMER_KEY, 9 | consumerSecret: process.env.WC_CONSUMER_SECRET, 10 | wpAPI: true, 11 | version: 'wc/v2' 12 | }); 13 | 14 | module.exports = { 15 | WooCommerce: WooCommerce 16 | }; 17 | -------------------------------------------------------------------------------- /api/routes/woo/index.js: -------------------------------------------------------------------------------- 1 | var wooRouter = require('express').Router({ 2 | mergeParams: true 3 | }); 4 | var bodyParser = require('body-parser') 5 | var jsonParser = bodyParser.json() 6 | 7 | // woocommerce Helper 8 | const helper = require('./wooHelper.js'); 9 | 10 | wooRouter.get('/', (req, res) => { 11 | res.status(200).json({ 12 | message: 'WooCommerce Router!' 13 | }); 14 | }); 15 | 16 | // route to trigger the capture 17 | wooRouter.post('/', jsonParser, function(req, res) { 18 | var event = req.body; 19 | console.log(JSON.stringify(event, null, 2)); // Mock 20 | 21 | helper.postProduct(event, function(err, data) { 22 | console.log(data); 23 | res.json(data); 24 | }); 25 | }); 26 | 27 | // route to trigger the capture 28 | wooRouter.get('/product/:id', function(req, res) { 29 | var event = req.body; 30 | const id = req.params.id; 31 | console.log(JSON.stringify(event, null, 2)); // Mock 32 | 33 | helper.getProduct(id, function(err, data) { 34 | console.log(data); 35 | res.json(data); 36 | }); 37 | }); 38 | 39 | module.exports = wooRouter; 40 | -------------------------------------------------------------------------------- /api/routes/woo/wooHelper.js: -------------------------------------------------------------------------------- 1 | const WooCommerceRestApi = require("@woocommerce/woocommerce-rest-api").default; 2 | const path = require('path'); 3 | const conf = require(path.join(process.env.APPDATA, "clipnuke", "config.json")); 4 | 5 | // Make sure user has filled out necessary info. 6 | if (conf.settings.woocommerce.site_url && conf.settings.woocommerce.consumer_key && conf.settings.woocommerce.consumer_secret) { 7 | // credentials 8 | var WooCommerce = new WooCommerceRestApi({ 9 | url: conf.settings.woocommerce.site_url, 10 | consumerKey: conf.settings.woocommerce.consumer_key, 11 | consumerSecret: conf.settings.woocommerce.consumer_secret, 12 | version: conf.settings.woocommerce.version || "wc/v3", 13 | queryStringAuth: conf.settings.woocommerce.query_string_auth || true 14 | }); 15 | } 16 | 17 | /** 18 | * Login to Xvideos. 19 | * Init a new webdriverio session. 20 | * @param {webdriverio} client A webdriverio client 21 | * @param {Function} callback err, data 22 | * @return {Object} A webdriverio cookie containing the authenticated PHPSESSID 23 | */ 24 | function postProduct(data, callback) { 25 | data.type = "variable"; 26 | data.status = "draft"; 27 | data.tax_status = "none"; 28 | data.tax_class = "Zero Rate"; 29 | data.attributes = []; 30 | data.attributes.push({ 31 | id: 4, 32 | name: "File Format", 33 | variation: true, 34 | options: ["HD 1080p MP4", "3-Day VOD Rental"] 35 | }); 36 | data.default_attributes = []; 37 | data.default_attributes.push({ 38 | id: 4, 39 | name: "File Format", 40 | option: "HD 1080p MP4" 41 | }); 42 | delete data.id; 43 | delete data.variations; 44 | // delete data.tags; 45 | delete data.images; // TEMP. Upload error b/c clipnuke.com isn't on the net. 46 | 47 | function removeMeta(obj) { 48 | for (prop in obj) { 49 | if (prop === 'id') 50 | delete obj[prop]; 51 | else if (typeof obj[prop] === 'object') 52 | removeMeta(obj[prop]); 53 | } 54 | } 55 | 56 | removeMeta(data.tags); 57 | removeMeta(data.images); 58 | removeMeta(data.categories); 59 | 60 | // WooCommerce.get("products/categories") 61 | // .then((response) => { 62 | // console.log(response.data); 63 | // }) 64 | // .catch((error) => { 65 | // console.log(error.response.data); 66 | // }); 67 | 68 | console.log(data); 69 | 70 | WooCommerce.post("products", data) 71 | .then((response) => { 72 | var id = response.data.id; 73 | console.log(response.data); 74 | var variation = {}; 75 | variation.regular_price = "1.99"; 76 | variation.tax_status = "none"; 77 | variation.tax_class = "Zero Rate"; 78 | variation.virtual = true; 79 | variation.attributes = []; 80 | variation.attributes.push({ 81 | id: 4, 82 | name: "File Format", 83 | option: "3-Day VOD Rental" 84 | }); 85 | 86 | /** Create Variations */ 87 | WooCommerce.post("products/" + id + "/variations", variation) 88 | .then((response) => { 89 | console.log(response.data); 90 | WooCommerce.post("products", data) 91 | .then((response) => { 92 | console.log(response.data); 93 | var variation = {}; 94 | variation.tax_status = "none"; 95 | variation.tax_class = "Zero Rate"; 96 | variation.virtual = true; 97 | variation.downloadable = true; 98 | variation.attributes = []; 99 | variation.attributes.push({ 100 | id: 4, 101 | name: "File Format", 102 | option: "HD 1080p MP4" 103 | }); 104 | 105 | /** Create Variations */ 106 | WooCommerce.post("products/" + id + "/variations", variation) 107 | .then((response) => { 108 | console.log(response.data); 109 | }) 110 | .catch((error) => { 111 | console.log(error.response.data); 112 | }); 113 | 114 | /** Callback */ 115 | // callback(null, response.data); 116 | }) 117 | .catch((error) => { 118 | console.log(error.response.data); 119 | }); 120 | }) 121 | .catch((error) => { 122 | console.log(error.response.data); 123 | }); 124 | 125 | /** Callback */ 126 | // callback(null, response.data); 127 | }) 128 | .catch((error) => { 129 | console.log(error.response.data); 130 | var msg = {}; 131 | msg.id = error.response.data.data.resource_id; 132 | msg.code = error.response.data.code; 133 | msg.msg = error.response.data.message; 134 | callback(error.message, msg); 135 | }); 136 | 137 | } 138 | 139 | function getProduct(id, callback) { 140 | WooCommerce.get("products/" + id) 141 | .then((response) => { 142 | console.log(response.data); 143 | callback(null, response.data); 144 | }) 145 | .catch((error) => { 146 | console.log(error.response.data); 147 | callback(error, error.response.data); 148 | }); 149 | } 150 | 151 | module.exports = { 152 | postProduct, 153 | getProduct 154 | }; 155 | -------------------------------------------------------------------------------- /api/routes/xvideos/index.js: -------------------------------------------------------------------------------- 1 | var xvideos = require('express').Router({ 2 | mergeParams: true 3 | }); 4 | // var sales = require('./sales') 5 | // var ftp = require('./ftp') 6 | var bodyParser = require('body-parser') 7 | var jsonParser = bodyParser.json() 8 | const path = require('path'); 9 | const spawn = require('child_process').spawn; // TODO Change to fork 10 | var cp = require('child_process'); 11 | 12 | // clips4sale Helper 13 | const xv = require('./xvHelper.js'); 14 | 15 | // Webdriver Client Instance 16 | const client = require('../../webdriverio/client.js').client; 17 | 18 | // Test cookie - Pre-authenticated 19 | // const cookie = require('./cookie.json'); 20 | 21 | // Test Route 22 | xvideos.get('/', (req, res) => { 23 | res.status(200).json({ 24 | message: 'Xvideos Router!' 25 | }); 26 | }); 27 | 28 | // route to trigger the capture 29 | xvideos.get('/uploads', function(req, res) { 30 | var id = req.params.id; 31 | console.log(`GET /uploads - Mock Endpoint`); // Mock 32 | res.json({}); 33 | }); 34 | 35 | // route to trigger the capture 36 | xvideos.post('/uploads', jsonParser, function(req, res) { 37 | var event = req.body; 38 | console.log(`POST /uploads - Mock Endpoint`); // Mock 39 | console.log(JSON.stringify(event, null, 2)); // Mock 40 | // res.json({}); // Mock Response 41 | var credentials = { 42 | user: conf.settings.xvideos.user, 43 | pass: conf.settings.xvideos.pass 44 | }; 45 | const params = { 46 | client: client, 47 | cookie: cookie 48 | }; 49 | xv.login(credentials, params, function(err, data) { 50 | xv.postUpload(event, params, function(err, data) { 51 | console.log(data); 52 | res.json(data); 53 | }); 54 | }); 55 | }); 56 | 57 | xvideos.post('/spawn', jsonParser, (req, res) => { 58 | const event = req.body; 59 | var child = cp.fork(path.join(__dirname, 'postVideo.js'), [JSON.stringify(event)]); 60 | // let child = spawn( 61 | // 'node', 62 | // [ 63 | // path.join(__dirname, 'postVideo.js'), 64 | // JSON.stringify(event) 65 | // ] 66 | // ); 67 | child.on('exit', (code) => { 68 | console.log(`Child process exited with code ${code}`); 69 | if (code === 0) { 70 | // res.status(200).json({ message: 'WebDriverIO ran successfully.' }); 71 | } else { 72 | // res.status(400).json({ message: 'Error code '+code }); 73 | } 74 | // res.status(200).json({ message: 'xxxmultimedia.com Router!' }); 75 | }); 76 | child.stdout.on('data', (data) => { 77 | console.log(`stdout: ${data}`); 78 | // res.status(200).json(data); 79 | }); 80 | child.stderr.on('data', (data) => { 81 | console.log(`stderr: ${data}`); 82 | // res.status(400).json(data); 83 | }); 84 | }); 85 | 86 | // route to trigger the capture 87 | xvideos.get('/uploads/:id', function(req, res) { 88 | var id = req.params.id; 89 | console.log(`Requesting Upload ID: ${id}`); 90 | // res.json({id}); 91 | var credentials = { 92 | user: conf.settings.xvideos.user, 93 | pass: conf.settings.xvideos.pass 94 | }; 95 | const params = { 96 | client: client, 97 | cookie: cookie 98 | }; 99 | 100 | xv.login(credentials, params, function(err, data) { 101 | 102 | xv.getUpload(id, params, function(err, data) { 103 | console.log(data); 104 | res.json(data); 105 | }); 106 | 107 | }); 108 | 109 | }); 110 | 111 | // route to trigger the capture 112 | xvideos.put('/uploads/:id', function(req, res) { 113 | var id = req.params.id; 114 | console.log(`PUT /uploads/${id} - Mock Endpoint`); // Mock 115 | res.json({}); 116 | }); 117 | 118 | // route to trigger the capture 119 | xvideos.delete('/uploads/:id', function(req, res) { 120 | var id = req.params.id; 121 | console.log(`DELETE /uploads/${id} - Mock Endpoint`); // Mock 122 | res.json({}); 123 | }); 124 | 125 | /** 126 | * Clips4Sale Router 127 | * @type {String} 128 | */ 129 | // xvideos.use('/sales', sales); 130 | 131 | // xvideos.use('/ftp', ftp); 132 | 133 | module.exports = xvideos; 134 | -------------------------------------------------------------------------------- /api/routes/xvideos/postVideo.js: -------------------------------------------------------------------------------- 1 | const dateutil = require('dateutil'); 2 | const dateFormat = require('dateformat'); 3 | const fs = require('fs'); 4 | const path = require('path'); 5 | var webdriverio = require('webdriverio'); 6 | var HashMap = require('hashmap'); 7 | 8 | // Webdriver Client Instance 9 | var config = { 10 | desiredCapabilities: { 11 | browserName: 'chrome', 12 | chromeOptions: { 13 | binary: path.join(__dirname, '../../../../bin/chromedriver.exe') 14 | }, 15 | }, 16 | singleton: true, // Enable persistent sessions 17 | debug: true, 18 | // host: "http://127.0.0.1", 19 | // port: 4444 20 | }; 21 | var client = webdriverio.remote(config); 22 | const conf = require(path.join(process.env.APPDATA, "clipnuke", "config.json")); 23 | 24 | console.log(process.argv); 25 | var event = JSON.parse(process.argv[2]); 26 | 27 | // Ass. Array - 28 | var video_premium = new HashMap(); 29 | video_premium 30 | .set("Free for All", "upload_form_video_premium_video_premium_centered_zone_all_site") 31 | .set("Paying Users", "upload_form_video_premium_video_premium_centered_zone_premium"); 32 | 33 | var networksites = new HashMap(); 34 | networksites 35 | .set("Xvideos Only", "upload_form_networksites_networksites_centered_networksites_DEFAULT_ONLY") 36 | .set("Xvideos & Network", "upload_form_networksites_networksites_centered_networksites_NO_RESTRICTION"); 37 | 38 | var category = new HashMap(); 39 | category 40 | .set("Straight", "upload_form_category_category_centered_category_straight") 41 | .set("Gay", "upload_form_category_category_centered_category_gay") 42 | .set("Shemale", "upload_form_category_category_centered_category_shemale"); 43 | 44 | // 45 | // var size = 0; 46 | // 47 | // minioClient.fGetObject('xxxmultimedia-downloads', event.filename, './tmp/'+event.filename, function(e) { 48 | // if (e) { 49 | // return console.log(e) 50 | // } 51 | // console.log('Done downloading. Starting HTTP server for local file on localhost.') 52 | // var stats = fs.statSync('./tmp/'+event.filename); 53 | // var fileSizeInBytes = stats.size; 54 | 55 | // Create HTTP server to serve URL upload option from. @todo kill on fail/success 56 | // http.createServer(function (req, res) { 57 | // console.log("Port Number : 3003"); 58 | // // change the MIME type to 'video/mp4' 59 | // res.writeHead(200, { 60 | // 'Content-Type': 'video/mp4', 61 | // 'Content-Length': fileSizeInBytes 62 | // }); 63 | // fs.exists('./tmp/'+event.filename,function(exists){ 64 | // if(exists) 65 | // { 66 | // var rstream = fs.createReadStream('./tmp/'+event.filename); 67 | // rstream.pipe(res); 68 | // } 69 | // else 70 | // { 71 | // res.send("Its a 404"); 72 | // res.end(); 73 | // } 74 | // }); 75 | // }).listen(3003); 76 | 77 | // Remove . and / from titles per C4S 78 | var name = event.name.replace('.', '').replace('/', ''); 79 | console.log(`Clean Title: ${name}`); 80 | var description = `${event.description}`; 81 | 82 | console.log(event); // Debug 83 | 84 | if (event["video_premium"] == "upload_form_video_premium_video_premium_centered_zone_premium") { 85 | params.client.click('#' + event["networksites"]); 86 | } 87 | 88 | /* var langCount = event["translations"].length; 89 | console.log(langCount); 90 | for (var i = 0; i < langCount.length; i++) { 91 | var iteration = i+1; 92 | params.client 93 | .click('#upload_form_title_translations_title_translations > button').pause(1000) 94 | .click('a[data-locale="' + event["translations"][iteration]["lang"] + '"]').pause(100) 95 | .setValue('#upload_form_title_translations_title_translations_tr_' + i + '_tr_' + i + '_title', event["translations"][iteration]["xvideosTitle"]).pause(100) 96 | } */ 97 | 98 | client.init() 99 | .url('https://www.xvideos.com/account') 100 | .pause(1000) 101 | // .waitForVisible('form', 3000) 102 | .setValue('body #signin-form_login', conf.settings.xvideos.user) 103 | .setValue('body #signin-form_password', conf.settings.xvideos.pass) 104 | // .submitForm('body #signin-form') 105 | .click('#signin-form > div.form-group.form-buttons > div > button') 106 | .pause(1000) 107 | // .init() 108 | /* .setCookie(params.cookie) */ 109 | .url('https://www.xvideos.com/account/uploads/new') 110 | .pause(1000) 111 | .click('input#' + event["video_premium"]) 112 | .click('input#' + event["category"]) 113 | .click('input#' + event["networksites"]) 114 | 115 | // Title & Description 116 | .setValue('textarea#upload_form_titledesc_description', event.description.substring(0, 500).replace(/<[^>]*>?/gm, '')) 117 | .setValue('input#upload_form_titledesc_title', event.name) 118 | .setValue('input#upload_form_titledesc_title_network', event.networkName).pause(100) 119 | 120 | // Select File HTTP(S) 121 | // .setValue('#upload_form_file_file_options_file_2_video_url', 'http://s3.xxxmultimedia.com:3003/'+event.filename).pause(100) 122 | // .click('#upload_form_file_file_options_file_2 > div > div > span > button').pause(100) 123 | // .click('#upload_form_file_file_options_file_2 > div > div > span').pause(1000) 124 | 125 | // Ads to display 126 | // .click('#upload_form_sponsorlinks_sponsorlinks_'+event.sponsoredLinks[0]).pause(100) 127 | .click('input#upload_form_sponsorlinks_sponsorlinks_19609').pause(100) 128 | 129 | // Agree to terms 130 | .click('#upload_form_file > div.form-group.form-field-upload_form_file_terms > div > div > label > div.checkbox-error-box').pause(1000) 131 | // Add tags 132 | .click('//*[@id="upload_form_tags"]/div/div/div[1]/div[1]/button').pause(100) 133 | .setValue('div.tag-list > input[type="text"]', event.tags[0] || '').pause(100) 134 | .click('//*[@id="upload_form_tags"]/div/div/div[1]/div[1]/button').pause(100) 135 | .click('//*[@id="upload_form_tags"]/div/div/div[1]/div[1]/button').pause(100) 136 | .setValue('div.tag-list > input[type="text"]', event.tags[1] || '').pause(100) 137 | .click('//*[@id="upload_form_tags"]/div/div/div[1]/div[1]/button').pause(100) 138 | .click('//*[@id="upload_form_tags"]/div/div/div[1]/div[1]/button').pause(100) 139 | .setValue('div.tag-list > input[type="text"]', event.tags[2] || '').pause(100) 140 | .click('//*[@id="upload_form_tags"]/div/div/div[1]/div[1]/button').pause(100) 141 | .click('//*[@id="upload_form_tags"]/div/div/div[1]/div[1]/button').pause(100) 142 | .setValue('div.tag-list > input[type="text"]', event.tags[3] || '').pause(100) 143 | .click('//*[@id="upload_form_tags"]/div/div/div[1]/div[1]/button').pause(100) 144 | .click('//*[@id="upload_form_tags"]/div/div/div[1]/div[1]/button').pause(100) 145 | .setValue('div.tag-list > input[type="text"]', event.tags[4] || '').pause(100) 146 | .click('//*[@id="upload_form_tags"]/div/div/div[1]/div[1]/button').pause(100) 147 | .click('//*[@id="upload_form_tags"]/div/div/div[1]/div[1]/button').pause(100) 148 | .setValue('div.tag-list > input[type="text"]', event.tags[5] || '').pause(100) 149 | .click('//*[@id="upload_form_tags"]/div/div/div[1]/div[1]/button').pause(100) 150 | .click('//*[@id="upload_form_tags"]/div/div/div[1]/div[1]/button').pause(100) 151 | .setValue('div.tag-list > input[type="text"]', event.tags[6] || '').pause(100) 152 | .click('//*[@id="upload_form_tags"]/div/div/div[1]/div[1]/button').pause(100) 153 | .click('//*[@id="upload_form_tags"]/div/div/div[1]/div[1]/button').pause(100) 154 | .setValue('div.tag-list > input[type="text"]', event.tags[7] || '').pause(100) 155 | .click('//*[@id="upload_form_tags"]/div/div/div[1]/div[1]/button').pause(100) 156 | .click('//*[@id="upload_form_tags"]/div/div/div[1]/div[1]/button').pause(100) 157 | .setValue('div.tag-list > input[type="text"]', event.tags[8] || '').pause(100) 158 | .click('//*[@id="upload_form_tags"]/div/div/div[1]/div[1]/button').pause(100) 159 | .click('//*[@id="upload_form_tags"]/div/div/div[1]/div[1]/button').pause(100) 160 | .setValue('div.tag-list > input[type="text"]', event.tags[9] || '').pause(100) 161 | .click('//*[@id="upload_form_tags"]/div/div/div[1]/div[1]/button').pause(100) 162 | .click('//*[@id="upload_form_tags"]/div/div/div[1]/div[1]/button').pause(100) 163 | .setValue('div.tag-list > input[type="text"]', event.tags[10] || '').pause(100) 164 | .click('//*[@id="upload_form_tags"]/div/div/div[1]/div[1]/button').pause(100) 165 | .click('//*[@id="upload_form_tags"]/div/div/div[1]/div[1]/button').pause(100) 166 | .setValue('div.tag-list > input[type="text"]', event.tags[11] || '').pause(100) 167 | .click('//*[@id="upload_form_tags"]/div/div/div[1]/div[1]/button').pause(100) 168 | .click('//*[@id="upload_form_tags"]/div/div/div[1]/div[1]/button').pause(100) 169 | .setValue('div.tag-list > input[type="text"]', event.tags[12] || '').pause(100) 170 | .click('//*[@id="upload_form_tags"]/div/div/div[1]/div[1]/button').pause(100) 171 | .click('//*[@id="upload_form_tags"]/div/div/div[1]/div[1]/button').pause(100) 172 | .setValue('div.tag-list > input[type="text"]', event.tags[13] || '').pause(100) 173 | .click('//*[@id="upload_form_tags"]/div/div/div[1]/div[1]/button').pause(100) 174 | .click('//*[@id="upload_form_tags"]/div/div/div[1]/div[1]/button').pause(100) 175 | .setValue('div.tag-list > input[type="text"]', event.tags[14] || '').pause(100) 176 | .click('//*[@id="upload_form_tags"]/div/div/div[1]/div[1]/button').pause(100) 177 | .click('//*[@id="upload_form_tags"]/div/div/div[1]/div[1]/button').pause(100) 178 | .setValue('div.tag-list > input[type="text"]', event.tags[15] || '').pause(100) 179 | .click('//*[@id="upload_form_tags"]/div/div/div[1]/div[1]/button').pause(100) 180 | .click('//*[@id="upload_form_tags"]/div/div/div[1]/div[1]/button').pause(100) 181 | .setValue('div.tag-list > input[type="text"]', event.tags[16] || '').pause(100) 182 | .click('//*[@id="upload_form_tags"]/div/div/div[1]/div[1]/button').pause(100) 183 | .click('//*[@id="upload_form_tags"]/div/div/div[1]/div[1]/button').pause(100) 184 | .setValue('div.tag-list > input[type="text"]', event.tags[17] || '').pause(100) 185 | .click('//*[@id="upload_form_tags"]/div/div/div[1]/div[1]/button').pause(100) 186 | .click('//*[@id="upload_form_tags"]/div/div/div[1]/div[1]/button').pause(100) 187 | .setValue('div.tag-list > input[type="text"]', event.tags[18] || '').pause(100) 188 | .click('//*[@id="upload_form_tags"]/div/div/div[1]/div[1]/button').pause(100) 189 | .click('//*[@id="upload_form_tags"]/div/div/div[1]/div[1]/button').pause(100) 190 | .setValue('div.tag-list > input[type="text"]', event.tags[19] || '').pause(100) 191 | .click('//*[@id="upload_form_tags"]/div/div/div[1]/div[1]/button').pause(100) 192 | 193 | .execute(function(event) { 194 | console.log(event); 195 | if (event["translations"][1]) { 196 | $('#upload_form_title_translations_title_translations > button').click(); 197 | $('a[data-locale="' + event["translations"][1]["lang"] + '"]').click(); 198 | $('#upload_form_title_translations_title_translations_tr_0_tr_0_title').val(event["translations"][1]["xvideosTitle"]); 199 | if (event["translations"][1]["lang"] && event["translations"][1]["networkTitle"]) { 200 | $('#upload_form_title_translations_title_network_translations_ntr_0 > div > div > div > span > button').click(); 201 | $('a[data-locale="' + event["translations"][1]["lang"] + '"]').click(); 202 | $('#upload_form_title_translations_title_network_translations_ntr_0_ntr_0_title').val(event["translations"][1]["networkTitle"]); 203 | } 204 | } 205 | if (event["translations"][2]) { 206 | $('#upload_form_title_translations_title_translations > button').click(); 207 | $('a[data-locale="' + event["translations"][2]["lang"] + '"]').click(); 208 | $('#upload_form_title_translations_title_translations_tr_1_tr_1_title').val(event["translations"][2]["xvideosTitle"]); 209 | if (event["translations"][2]["lang"] && event["translations"][2]["networkTitle"]) { 210 | $('#upload_form_title_translations_title_network_translations > button').click(); 211 | $('a[data-locale="' + event["translations"][2]["lang"] + '"]').click(); 212 | $('#upload_form_title_translations_title_network_translations_ntr_1_ntr_1_title').val(event["translations"][2]["networkTitle"]); 213 | } 214 | } 215 | if (event["translations"][3]) { 216 | $('#upload_form_title_translations_title_translations > button').click(); 217 | $('a[data-locale="' + event["translations"][3]["lang"] + '"]').click(); 218 | $('#upload_form_title_translations_title_translations_tr_2_tr_2_title').val(event["translations"][3]["xvideosTitle"]); 219 | if (event["translations"][3]["lang"] && event["translations"][3]["networkTitle"]) { 220 | $('#upload_form_title_translations_title_network_translations > button').click(); 221 | $('a[data-locale="' + event["translations"][3]["lang"] + '"]').click(); 222 | $('#upload_form_title_translations_title_network_translations_ntr_2_ntr_2_title').val(event["translations"][3]["networkTitle"]); 223 | } 224 | } 225 | if (event["translations"][4]) { 226 | $('#upload_form_title_translations_title_translations > button').click(); 227 | $('a[data-locale="' + event["translations"][4]["lang"] + '"]').click(); 228 | $('#upload_form_title_translations_title_translations_tr_3_tr_3_title').val(event["translations"][4]["xvideosTitle"]); 229 | if (event["translations"][4]["lang"] && event["translations"][4]["networkTitle"]) { 230 | $('#upload_form_title_translations_title_network_translations > button').click(); 231 | $('a[data-locale="' + event["translations"][4]["lang"] + '"]').click(); 232 | $('#upload_form_title_translations_title_network_translations_ntr_3_ntr_3_title').val(event["translations"][4]["networkTitle"]); 233 | } 234 | } 235 | if (event["translations"][5]) { 236 | $('#upload_form_title_translations_title_translations > button').click(); 237 | $('a[data-locale="' + event["translations"][5]["lang"] + '"]').click(); 238 | $('#upload_form_title_translations_title_translations_tr_4_tr_4_title').val(event["translations"][5]["xvideosTitle"]); 239 | if (event["translations"][5]["lang"] && event["translations"][5]["networkTitle"]) { 240 | $('#upload_form_title_translations_title_network_translations > button').click(); 241 | $('a[data-locale="' + event["translations"][5]["lang"] + '"]').click(); 242 | $('#upload_form_title_translations_title_network_translations_ntr_4_ntr_4_title').val(event["translations"][5]["networkTitle"]); 243 | } 244 | } 245 | if (event["translations"][6]) { 246 | $('#upload_form_title_translations_title_translations > button').click(); 247 | $('a[data-locale="' + event["translations"][6]["lang"] + '"]').click(); 248 | $('#upload_form_title_translations_title_translations_tr_5_tr_5_title').val(event["translations"][6]["xvideosTitle"]); 249 | if (event["translations"][6]["lang"] && event["translations"][6]["networkTitle"]) { 250 | $('#upload_form_title_translations_title_network_translations > button').click(); 251 | $('a[data-locale="' + event["translations"][6]["lang"] + '"]').click(); 252 | $('#upload_form_title_translations_title_network_translations_ntr_5_ntr_5_title').val(event["translations"][6]["networkTitle"]); 253 | } 254 | } 255 | if (event["translations"][7]) { 256 | $('#upload_form_title_translations_title_translations > button').click(); 257 | $('a[data-locale="' + event["translations"][7]["lang"] + '"]').click(); 258 | $('#upload_form_title_translations_title_translations_tr_6_tr_6_title').val(event["translations"][7]["xvideosTitle"]); 259 | if (event["translations"][7]["lang"] && event["translations"][7]["networkTitle"]) { 260 | $('#upload_form_title_translations_title_network_translations > button').click(); 261 | $('a[data-locale="' + event["translations"][7]["lang"] + '"]').click(); 262 | $('#upload_form_title_translations_title_network_translations_ntr_6_ntr_6_title').val(event["translations"][7]["networkTitle"]); 263 | } 264 | } 265 | if (event["translations"][8]) { 266 | $('#upload_form_title_translations_title_translations > button').click(); 267 | $('a[data-locale="' + event["translations"][8]["lang"] + '"]').click(); 268 | $('#upload_form_title_translations_title_translations_tr_7_tr_7_title').val(event["translations"][8]["xvideosTitle"]); 269 | if (event["translations"][8]["lang"] && event["translations"][8]["networkTitle"]) { 270 | $('#upload_form_title_translations_title_network_translations > button').click(); 271 | $('a[data-locale="' + event["translations"][8]["lang"] + '"]').click(); 272 | $('#upload_form_title_translations_title_network_translations_ntr_7_ntr_7_title').val(event["translations"][8]["networkTitle"]); 273 | } 274 | } 275 | if (event["translations"][9]) { 276 | $('#upload_form_title_translations_title_translations > button').click(); 277 | $('a[data-locale="' + event["translations"][9]["lang"] + '"]').click(); 278 | $('#upload_form_title_translations_title_translations_tr_8_tr_8_title').val(event["translations"][9]["xvideosTitle"]); 279 | if (event["translations"][9]["lang"] && event["translations"][9]["networkTitle"]) { 280 | $('#upload_form_title_translations_title_network_translations > button').click(); 281 | $('a[data-locale="' + event["translations"][9]["lang"] + '"]').click(); 282 | $('#upload_form_title_translations_title_network_translations_ntr_8_ntr_8_title').val(event["translations"][9]["networkTitle"]); 283 | } 284 | } 285 | if (event["translations"][10]) { 286 | $('#upload_form_title_translations_title_translations > button').click(); 287 | $('a[data-locale="' + event["translations"][10]["lang"] + '"]').click(); 288 | $('#upload_form_title_translations_title_translations_tr_9_tr_9_title').val(event["translations"][10]["xvideosTitle"]); 289 | if (event["translations"][10]["lang"] && event["translations"][10]["networkTitle"]) { 290 | $('#upload_form_title_translations_title_network_translations > button').click(); 291 | $('a[data-locale="' + event["translations"][10]["lang"] + '"]').click(); 292 | $('#upload_form_title_translations_title_network_translations_ntr_8_ntr_8_title').val(event["translations"][10]["networkTitle"]); 293 | } 294 | } 295 | return; 296 | }, event) 297 | .pause(1000) 298 | 299 | // Submit form 300 | // .click('#upload_form_file_file_options > div > div > span:nth-child(3) > button').pause(1000) 301 | 302 | // .waitForVisible('#upload-form-progress', 900000).then(console.log('Now uploading your clip. Please wait.')) // Wait 10 minutes for the form to be complete and uploaded. Else fail 303 | .waitForVisible('#upload-form-progress > h5.status.text-success', 999999999).pause(10000) 304 | .execute(function(event) { 305 | console.log(event); 306 | $('h5 > span.text-success > a.text-success').href; 307 | }, event) 308 | .then(function() { 309 | params.client.end(); 310 | }) 311 | /** Success Callback */ 312 | // .waitUntil(() => { 313 | // var elem = $('iframe#iframe-upload').contents(); 314 | // return $("#iframeID").contents().find("[tokenid=" + token + "]").html(); 315 | // }, 300000, 'expected text to be different after 5s'); 316 | .next(function() { 317 | console.log('Done!'); 318 | console.log(JSON.stringify(event, null, 2)); 319 | // params.client.end(); // Stable version only 320 | return callback(null, event); 321 | }) 322 | 323 | // Global Error Callback 324 | .catch((e) => { 325 | params.client.end(); // Stable version only 326 | console.log(e); 327 | return callback(null, event); 328 | }); 329 | -------------------------------------------------------------------------------- /api/routes/xvideos/xvHelper.js: -------------------------------------------------------------------------------- 1 | const dateutil = require('dateutil'); 2 | const dateFormat = require('dateformat'); 3 | var http = require('http'); 4 | var fs = require('fs'); 5 | var path = require('path'); 6 | var Minio = require('minio'); 7 | var HashMap = require('hashmap'); 8 | 9 | /** 10 | * Login to Xvideos. 11 | * Init a new webdriverio session. 12 | * @param {webdriverio} client A webdriverio client 13 | * @param {Function} callback err, data 14 | * @return {Object} A webdriverio cookie containing the authenticated PHPSESSID 15 | */ 16 | function auth(credentials, params, callback) { 17 | console.log(credentials); 18 | params.client 19 | .init() 20 | .url('https://www.xvideos.com/account') 21 | .pause(1000) 22 | // .waitForVisible('form', 3000) 23 | .setValue('body #signin-form_login', credentials.user) 24 | .setValue('body #signin-form_password', credentials.pass) 25 | // .submitForm('body #signin-form') 26 | .click('#signin-form > div.form-group.form-buttons > div > button') 27 | .pause(1000) 28 | // .pause(15000) // Wait in case we need to solve a recaptcha. 29 | /* .getCookie([{"domain":"admin.clips4sale.com","httpOnly":false,"name":"PHPSESSID","path":"/","secure":false,"value":"jt0p2kiigvqdps9paqn6nqpnm8"}]).then(function(cookie) { 30 | var json = JSON.stringify(cookie); 31 | console.log('Cookie is: ' + json); 32 | fs.writeFile('cookie.json', json, 'utf8', callback); 33 | return cookie; 34 | }) */ 35 | .next(function(data) { 36 | console.log(data); 37 | return callback(null, data); 38 | }).catch((e) => console.log(e)); 39 | }; 40 | 41 | /** 42 | * Edit Vid - Details 43 | * Sends a GET request to the server, using an authenticated webdriverio session, fetches the data, then ends the session. 44 | * NOTE: It's super important to use .end() method to end the browser session. Because {@link auth | auth} calls init() to open a new browser session. 45 | * IMPORTANT: If we don't run browser.end(), this app will fail when {@link getVid | getVid} or another method is called! 46 | * @param {Integer} id A ManyVids Video ID 47 | * @param {Object} params client, cookie 48 | * @param {Function} callback [description] 49 | * @return {Object} An object containing details about a ManyVids video. 50 | */ 51 | function getUpload(id, params, callback) { 52 | var data = {}; 53 | var dateObj = {}; 54 | var formData = {}; 55 | formData.translations = []; 56 | formData.translations.push({}); 57 | formData.tags = []; 58 | 59 | params.client 60 | /* .setCookie(params.cookie) */ 61 | .url(`https://www.xvideos.com/account/uploads/${id}/edit`) 62 | .pause(1000) 63 | 64 | /* Title & Description */ 65 | // Xvideos Title 66 | .getValue('#edit_form_titledesc_title').then(function(val) { 67 | formData.translations[0].xvideosName = val; 68 | }) 69 | // Xvideos Lang 70 | .getValue('#edit_form_titledesc_title_lang').then(function(val) { 71 | formData.translations[0].xvideosLang = val; 72 | }) 73 | 74 | // Xvideos Title 75 | .getValue('#edit_form_titledesc_title_network').then(function(val) { 76 | formData.translations[0].networkName = val; 77 | }) 78 | // Xvideos Lang 79 | .getValue('#edit_form_titledesc_title_network_lang').then(function(val) { 80 | formData.translations[0].networkLang = val; 81 | }) 82 | 83 | // Translations 84 | .getAttribute('#edit_form_title_translations_title_network_translations_ntr_0_ntr_0_title_lang', 'value').then(function(val) { 85 | formData.translations.push({}); 86 | formData.translations[1].xvideosLang = val; 87 | }) 88 | .getAttribute('#edit_form_title_translations_title_network_translations_ntr_0_ntr_0_title_lang', 'value').then(function(val) { 89 | formData.lang = val; 90 | }) 91 | /* .getAttribute('#edit_form_title_translations_title_translations_tr_0_tr_0_title_lang', 'value').then(function(val) { 92 | // console.log('key1 is: ' + JSON.stringify(val)); 93 | if(val !== null && val !== '' && val !== 'Select Related Categories') { 94 | formData.relatedCategories.push(val); 95 | } 96 | }) */ 97 | /* .execute(function(data) { 98 | data.translations = []; 99 | var obj = { 100 | lang: jQuery('#edit_form_title_translations_title_translations_tr_0_tr_0_title_lang')[0].value, 101 | xvideos: jQuery('input[name="edit_form[title_translations][title_translations][tr_0][tr_0_title_lang]"]')[0].value, 102 | network: jQuery('input[name="edit_form[title_translations][title_translations][tr_0][tr_0_title_lang]"]')[0].value 103 | }; 104 | data.translations.push(obj); 105 | return data.translations; 106 | }, data).then(function(data) { 107 | formData.translations = data.translations; 108 | console.log(formData.translations); 109 | }) */ 110 | 111 | // Success Callback 112 | .next(function() { 113 | params.client.end(); /** Ends browser session {@link editVid| read editVids docs} */ 114 | console.log('Done!'); 115 | console.log(JSON.stringify(formData, null, 2)); 116 | return callback(null, formData); 117 | }) 118 | 119 | // Global Error Callback 120 | .catch((e) => { 121 | console.log(e); 122 | // params.client.end(); /** Ends browser session {@link editVid| read editVids docs} */ 123 | return callback(e, { 124 | msg: "A global error ocurred. Please check the app." 125 | }); 126 | }); 127 | }; 128 | 129 | /** 130 | * Create New Clip 131 | * @param {Integer} event The clip data 132 | * @param {Object} params client, cookie 133 | * @param {Function} callback [description] 134 | * @return {Object} [description] 135 | */ 136 | function postUpload(event, params, callback) { 137 | // Allow insecure TLS connections 138 | process.env['NODE_TLS_REJECT_UNAUTHORIZED'] = '0'; 139 | 140 | // Custom command 141 | /* params.client.addCommand("getUrlAndTitle", function (customVar) { 142 | // `this` refers to the `browser` scope 143 | return { 144 | url: this.getUrl(), 145 | title: this.getTitle(), 146 | customVar: customVar 147 | }; 148 | }); */ 149 | 150 | // Ass. Array - 151 | var video_premium = new HashMap(); 152 | video_premium 153 | .set("Free for All", "upload_form_video_premium_video_premium_centered_zone_all_site") 154 | .set("Paying Users", "upload_form_video_premium_video_premium_centered_zone_premium"); 155 | 156 | var networksites = new HashMap(); 157 | networksites 158 | .set("Xvideos Only", "upload_form_networksites_networksites_centered_networksites_DEFAULT_ONLY") 159 | .set("Xvideos & Network", "upload_form_networksites_networksites_centered_networksites_NO_RESTRICTION"); 160 | 161 | var category = new HashMap(); 162 | category 163 | .set("Straight", "upload_form_category_category_centered_category_straight") 164 | .set("Gay", "upload_form_category_category_centered_category_gay") 165 | .set("Shemale", "upload_form_category_category_centered_category_shemale"); 166 | 167 | // Setup minio client 168 | // var minioClient = new Minio.Client({ 169 | // endPoint: '', 170 | // port: 9000, 171 | // useSSL: true, 172 | // accessKey: '', 173 | // secretKey: '' 174 | // }); 175 | // 176 | // var size = 0; 177 | // 178 | // minioClient.fGetObject('bucket', event.filename, './tmp/'+event.filename, function(e) { 179 | // if (e) { 180 | // return console.log(e) 181 | // } 182 | // console.log('Done downloading. Starting HTTP server for local file on localhost.') 183 | // var stats = fs.statSync('./tmp/'+event.filename); 184 | // var fileSizeInBytes = stats.size; 185 | 186 | // Create HTTP server to serve URL upload option from. @todo kill on fail/success 187 | // http.createServer(function (req, res) { 188 | // console.log("Port Number : 3003"); 189 | // // change the MIME type to 'video/mp4' 190 | // res.writeHead(200, { 191 | // 'Content-Type': 'video/mp4', 192 | // 'Content-Length': fileSizeInBytes 193 | // }); 194 | // fs.exists('./tmp/'+event.filename,function(exists){ 195 | // if(exists) 196 | // { 197 | // var rstream = fs.createReadStream('./tmp/'+event.filename); 198 | // rstream.pipe(res); 199 | // } 200 | // else 201 | // { 202 | // res.send("Its a 404"); 203 | // res.end(); 204 | // } 205 | // }); 206 | // }).listen(3003); 207 | 208 | // Remove . and / from titles per C4S 209 | var name = event.name.replace('.', '').replace('/', ''); 210 | console.log(`Clean Title: ${name}`); 211 | var description = `${event.description}`; 212 | 213 | console.log(event, params); // Debug 214 | 215 | if (event["video_premium"] == "upload_form_video_premium_video_premium_centered_zone_premium") { 216 | params.client.click('#' + event["networksites"]); 217 | } 218 | 219 | /* var langCount = event["translations"].length; 220 | console.log(langCount); 221 | for (var i = 0; i < langCount.length; i++) { 222 | var iteration = i+1; 223 | params.client 224 | .click('#upload_form_title_translations_title_translations > button').pause(1000) 225 | .click('a[data-locale="' + event["translations"][iteration]["lang"] + '"]').pause(100) 226 | .setValue('#upload_form_title_translations_title_translations_tr_' + i + '_tr_' + i + '_title', event["translations"][iteration]["xvideosTitle"]).pause(100) 227 | } */ 228 | 229 | params.client 230 | // .init() 231 | /* .setCookie(params.cookie) */ 232 | .url('https://www.xvideos.com/account/uploads/new') 233 | .pause(1000) 234 | .click('input#' + event["video_premium"]) 235 | .click('input#' + event["category"]) 236 | .click('input#' + event["networksites"]) 237 | 238 | // Title & Description 239 | .setValue('textarea#upload_form_titledesc_description', event.description.substring(0, 500).replace(/<[^>]*>?/gm, '')) 240 | .setValue('input#upload_form_titledesc_title', event.name) 241 | .setValue('input#upload_form_titledesc_title_network', event.networkName).pause(100) 242 | 243 | // Select File HTTP(S) 244 | // .setValue('#upload_form_file_file_options_file_2_video_url', 'http://s3.xxxmultimedia.com:3003/'+event.filename).pause(100) 245 | // .click('#upload_form_file_file_options_file_2 > div > div > span > button').pause(100) 246 | // .click('#upload_form_file_file_options_file_2 > div > div > span').pause(1000) 247 | 248 | // Ads to display 249 | // .click('#upload_form_sponsorlinks_sponsorlinks_'+event.sponsoredLinks[0]).pause(100) 250 | .click('input#upload_form_sponsorlinks_sponsorlinks_19609').pause(100) 251 | 252 | // Agree to terms 253 | .click('#upload_form_file > div.form-group.form-field-upload_form_file_terms > div > div > label > div.checkbox-error-box').pause(1000) 254 | // Add tags 255 | .click('//*[@id="upload_form_tags"]/div/div/div[1]/div[1]/button').pause(100) 256 | .setValue('div.tag-list > input[type="text"]', event.tags[0] || '').pause(100) 257 | .click('//*[@id="upload_form_tags"]/div/div/div[1]/div[1]/button').pause(100) 258 | .click('//*[@id="upload_form_tags"]/div/div/div[1]/div[1]/button').pause(100) 259 | .setValue('div.tag-list > input[type="text"]', event.tags[1] || '').pause(100) 260 | .click('//*[@id="upload_form_tags"]/div/div/div[1]/div[1]/button').pause(100) 261 | .click('//*[@id="upload_form_tags"]/div/div/div[1]/div[1]/button').pause(100) 262 | .setValue('div.tag-list > input[type="text"]', event.tags[2] || '').pause(100) 263 | .click('//*[@id="upload_form_tags"]/div/div/div[1]/div[1]/button').pause(100) 264 | .click('//*[@id="upload_form_tags"]/div/div/div[1]/div[1]/button').pause(100) 265 | .setValue('div.tag-list > input[type="text"]', event.tags[3] || '').pause(100) 266 | .click('//*[@id="upload_form_tags"]/div/div/div[1]/div[1]/button').pause(100) 267 | .click('//*[@id="upload_form_tags"]/div/div/div[1]/div[1]/button').pause(100) 268 | .setValue('div.tag-list > input[type="text"]', event.tags[4] || '').pause(100) 269 | .click('//*[@id="upload_form_tags"]/div/div/div[1]/div[1]/button').pause(100) 270 | .click('//*[@id="upload_form_tags"]/div/div/div[1]/div[1]/button').pause(100) 271 | .setValue('div.tag-list > input[type="text"]', event.tags[5] || '').pause(100) 272 | .click('//*[@id="upload_form_tags"]/div/div/div[1]/div[1]/button').pause(100) 273 | .click('//*[@id="upload_form_tags"]/div/div/div[1]/div[1]/button').pause(100) 274 | .setValue('div.tag-list > input[type="text"]', event.tags[6] || '').pause(100) 275 | .click('//*[@id="upload_form_tags"]/div/div/div[1]/div[1]/button').pause(100) 276 | .click('//*[@id="upload_form_tags"]/div/div/div[1]/div[1]/button').pause(100) 277 | .setValue('div.tag-list > input[type="text"]', event.tags[7] || '').pause(100) 278 | .click('//*[@id="upload_form_tags"]/div/div/div[1]/div[1]/button').pause(100) 279 | .click('//*[@id="upload_form_tags"]/div/div/div[1]/div[1]/button').pause(100) 280 | .setValue('div.tag-list > input[type="text"]', event.tags[8] || '').pause(100) 281 | .click('//*[@id="upload_form_tags"]/div/div/div[1]/div[1]/button').pause(100) 282 | .click('//*[@id="upload_form_tags"]/div/div/div[1]/div[1]/button').pause(100) 283 | .setValue('div.tag-list > input[type="text"]', event.tags[9] || '').pause(100) 284 | .click('//*[@id="upload_form_tags"]/div/div/div[1]/div[1]/button').pause(100) 285 | .click('//*[@id="upload_form_tags"]/div/div/div[1]/div[1]/button').pause(100) 286 | .setValue('div.tag-list > input[type="text"]', event.tags[10] || '').pause(100) 287 | .click('//*[@id="upload_form_tags"]/div/div/div[1]/div[1]/button').pause(100) 288 | .click('//*[@id="upload_form_tags"]/div/div/div[1]/div[1]/button').pause(100) 289 | .setValue('div.tag-list > input[type="text"]', event.tags[11] || '').pause(100) 290 | .click('//*[@id="upload_form_tags"]/div/div/div[1]/div[1]/button').pause(100) 291 | .click('//*[@id="upload_form_tags"]/div/div/div[1]/div[1]/button').pause(100) 292 | .setValue('div.tag-list > input[type="text"]', event.tags[12] || '').pause(100) 293 | .click('//*[@id="upload_form_tags"]/div/div/div[1]/div[1]/button').pause(100) 294 | .click('//*[@id="upload_form_tags"]/div/div/div[1]/div[1]/button').pause(100) 295 | .setValue('div.tag-list > input[type="text"]', event.tags[13] || '').pause(100) 296 | .click('//*[@id="upload_form_tags"]/div/div/div[1]/div[1]/button').pause(100) 297 | .click('//*[@id="upload_form_tags"]/div/div/div[1]/div[1]/button').pause(100) 298 | .setValue('div.tag-list > input[type="text"]', event.tags[14] || '').pause(100) 299 | .click('//*[@id="upload_form_tags"]/div/div/div[1]/div[1]/button').pause(100) 300 | .click('//*[@id="upload_form_tags"]/div/div/div[1]/div[1]/button').pause(100) 301 | .setValue('div.tag-list > input[type="text"]', event.tags[15] || '').pause(100) 302 | .click('//*[@id="upload_form_tags"]/div/div/div[1]/div[1]/button').pause(100) 303 | .click('//*[@id="upload_form_tags"]/div/div/div[1]/div[1]/button').pause(100) 304 | .setValue('div.tag-list > input[type="text"]', event.tags[16] || '').pause(100) 305 | .click('//*[@id="upload_form_tags"]/div/div/div[1]/div[1]/button').pause(100) 306 | .click('//*[@id="upload_form_tags"]/div/div/div[1]/div[1]/button').pause(100) 307 | .setValue('div.tag-list > input[type="text"]', event.tags[17] || '').pause(100) 308 | .click('//*[@id="upload_form_tags"]/div/div/div[1]/div[1]/button').pause(100) 309 | .click('//*[@id="upload_form_tags"]/div/div/div[1]/div[1]/button').pause(100) 310 | .setValue('div.tag-list > input[type="text"]', event.tags[18] || '').pause(100) 311 | .click('//*[@id="upload_form_tags"]/div/div/div[1]/div[1]/button').pause(100) 312 | .click('//*[@id="upload_form_tags"]/div/div/div[1]/div[1]/button').pause(100) 313 | .setValue('div.tag-list > input[type="text"]', event.tags[19] || '').pause(100) 314 | .click('//*[@id="upload_form_tags"]/div/div/div[1]/div[1]/button').pause(100) 315 | 316 | .execute(function(event) { 317 | console.log(event); 318 | if (event["translations"][1]) { 319 | $('#upload_form_title_translations_title_translations > button').click(); 320 | $('a[data-locale="' + event["translations"][1]["lang"] + '"]').click(); 321 | $('#upload_form_title_translations_title_translations_tr_0_tr_0_title').val(event["translations"][1]["xvideosTitle"]); 322 | if (event["translations"][1]["lang"] && event["translations"][1]["networkTitle"]) { 323 | $('#upload_form_title_translations_title_network_translations_ntr_0 > div > div > div > span > button').click(); 324 | $('a[data-locale="' + event["translations"][1]["lang"] + '"]').click(); 325 | $('#upload_form_title_translations_title_network_translations_ntr_0_ntr_0_title').val(event["translations"][1]["networkTitle"]); 326 | } 327 | } 328 | if (event["translations"][2]) { 329 | $('#upload_form_title_translations_title_translations > button').click(); 330 | $('a[data-locale="' + event["translations"][2]["lang"] + '"]').click(); 331 | $('#upload_form_title_translations_title_translations_tr_1_tr_1_title').val(event["translations"][2]["xvideosTitle"]); 332 | if (event["translations"][2]["lang"] && event["translations"][2]["networkTitle"]) { 333 | $('#upload_form_title_translations_title_network_translations > button').click(); 334 | $('a[data-locale="' + event["translations"][2]["lang"] + '"]').click(); 335 | $('#upload_form_title_translations_title_network_translations_ntr_1_ntr_1_title').val(event["translations"][2]["networkTitle"]); 336 | } 337 | } 338 | if (event["translations"][3]) { 339 | $('#upload_form_title_translations_title_translations > button').click(); 340 | $('a[data-locale="' + event["translations"][3]["lang"] + '"]').click(); 341 | $('#upload_form_title_translations_title_translations_tr_2_tr_2_title').val(event["translations"][3]["xvideosTitle"]); 342 | if (event["translations"][3]["lang"] && event["translations"][3]["networkTitle"]) { 343 | $('#upload_form_title_translations_title_network_translations > button').click(); 344 | $('a[data-locale="' + event["translations"][3]["lang"] + '"]').click(); 345 | $('#upload_form_title_translations_title_network_translations_ntr_2_ntr_2_title').val(event["translations"][3]["networkTitle"]); 346 | } 347 | } 348 | if (event["translations"][4]) { 349 | $('#upload_form_title_translations_title_translations > button').click(); 350 | $('a[data-locale="' + event["translations"][4]["lang"] + '"]').click(); 351 | $('#upload_form_title_translations_title_translations_tr_3_tr_3_title').val(event["translations"][4]["xvideosTitle"]); 352 | if (event["translations"][4]["lang"] && event["translations"][4]["networkTitle"]) { 353 | $('#upload_form_title_translations_title_network_translations > button').click(); 354 | $('a[data-locale="' + event["translations"][4]["lang"] + '"]').click(); 355 | $('#upload_form_title_translations_title_network_translations_ntr_3_ntr_3_title').val(event["translations"][4]["networkTitle"]); 356 | } 357 | } 358 | if (event["translations"][5]) { 359 | $('#upload_form_title_translations_title_translations > button').click(); 360 | $('a[data-locale="' + event["translations"][5]["lang"] + '"]').click(); 361 | $('#upload_form_title_translations_title_translations_tr_4_tr_4_title').val(event["translations"][5]["xvideosTitle"]); 362 | if (event["translations"][5]["lang"] && event["translations"][5]["networkTitle"]) { 363 | $('#upload_form_title_translations_title_network_translations > button').click(); 364 | $('a[data-locale="' + event["translations"][5]["lang"] + '"]').click(); 365 | $('#upload_form_title_translations_title_network_translations_ntr_4_ntr_4_title').val(event["translations"][5]["networkTitle"]); 366 | } 367 | } 368 | if (event["translations"][6]) { 369 | $('#upload_form_title_translations_title_translations > button').click(); 370 | $('a[data-locale="' + event["translations"][6]["lang"] + '"]').click(); 371 | $('#upload_form_title_translations_title_translations_tr_5_tr_5_title').val(event["translations"][6]["xvideosTitle"]); 372 | if (event["translations"][6]["lang"] && event["translations"][6]["networkTitle"]) { 373 | $('#upload_form_title_translations_title_network_translations > button').click(); 374 | $('a[data-locale="' + event["translations"][6]["lang"] + '"]').click(); 375 | $('#upload_form_title_translations_title_network_translations_ntr_5_ntr_5_title').val(event["translations"][6]["networkTitle"]); 376 | } 377 | } 378 | if (event["translations"][7]) { 379 | $('#upload_form_title_translations_title_translations > button').click(); 380 | $('a[data-locale="' + event["translations"][7]["lang"] + '"]').click(); 381 | $('#upload_form_title_translations_title_translations_tr_6_tr_6_title').val(event["translations"][7]["xvideosTitle"]); 382 | if (event["translations"][7]["lang"] && event["translations"][7]["networkTitle"]) { 383 | $('#upload_form_title_translations_title_network_translations > button').click(); 384 | $('a[data-locale="' + event["translations"][7]["lang"] + '"]').click(); 385 | $('#upload_form_title_translations_title_network_translations_ntr_6_ntr_6_title').val(event["translations"][7]["networkTitle"]); 386 | } 387 | } 388 | if (event["translations"][8]) { 389 | $('#upload_form_title_translations_title_translations > button').click(); 390 | $('a[data-locale="' + event["translations"][8]["lang"] + '"]').click(); 391 | $('#upload_form_title_translations_title_translations_tr_7_tr_7_title').val(event["translations"][8]["xvideosTitle"]); 392 | if (event["translations"][8]["lang"] && event["translations"][8]["networkTitle"]) { 393 | $('#upload_form_title_translations_title_network_translations > button').click(); 394 | $('a[data-locale="' + event["translations"][8]["lang"] + '"]').click(); 395 | $('#upload_form_title_translations_title_network_translations_ntr_7_ntr_7_title').val(event["translations"][8]["networkTitle"]); 396 | } 397 | } 398 | if (event["translations"][9]) { 399 | $('#upload_form_title_translations_title_translations > button').click(); 400 | $('a[data-locale="' + event["translations"][9]["lang"] + '"]').click(); 401 | $('#upload_form_title_translations_title_translations_tr_8_tr_8_title').val(event["translations"][9]["xvideosTitle"]); 402 | if (event["translations"][9]["lang"] && event["translations"][9]["networkTitle"]) { 403 | $('#upload_form_title_translations_title_network_translations > button').click(); 404 | $('a[data-locale="' + event["translations"][9]["lang"] + '"]').click(); 405 | $('#upload_form_title_translations_title_network_translations_ntr_8_ntr_8_title').val(event["translations"][9]["networkTitle"]); 406 | } 407 | } 408 | if (event["translations"][10]) { 409 | $('#upload_form_title_translations_title_translations > button').click(); 410 | $('a[data-locale="' + event["translations"][10]["lang"] + '"]').click(); 411 | $('#upload_form_title_translations_title_translations_tr_9_tr_9_title').val(event["translations"][10]["xvideosTitle"]); 412 | if (event["translations"][10]["lang"] && event["translations"][10]["networkTitle"]) { 413 | $('#upload_form_title_translations_title_network_translations > button').click(); 414 | $('a[data-locale="' + event["translations"][10]["lang"] + '"]').click(); 415 | $('#upload_form_title_translations_title_network_translations_ntr_8_ntr_8_title').val(event["translations"][10]["networkTitle"]); 416 | } 417 | } 418 | return; 419 | }, event) 420 | .pause(1000) 421 | 422 | // Submit form 423 | // .click('#upload_form_file_file_options > div > div > span:nth-child(3) > button').pause(1000) 424 | 425 | // .waitForVisible('#upload-form-progress', 900000).then(console.log('Now uploading your clip. Please wait.')) // Wait 10 minutes for the form to be complete and uploaded. Else fail 426 | .waitForVisible('#upload-form-progress > h5.status.text-success', 999999999).pause(10000) 427 | .execute(function(event) { 428 | console.log(event); 429 | $('h5 > span.text-success > a.text-success').href; 430 | }, event) 431 | .then(function() { 432 | params.client.end(); 433 | }) 434 | /** Success Callback */ 435 | // .waitUntil(() => { 436 | // var elem = $('iframe#iframe-upload').contents(); 437 | // return $("#iframeID").contents().find("[tokenid=" + token + "]").html(); 438 | // }, 300000, 'expected text to be different after 5s'); 439 | .next(function() { 440 | console.log('Done!'); 441 | console.log(JSON.stringify(event, null, 2)); 442 | // params.client.end(); // Stable version only 443 | return callback(null, event); 444 | }) 445 | 446 | // Global Error Callback 447 | .catch((e) => { 448 | params.client.end(); // Stable version only 449 | console.log(e); 450 | return callback(null, event); 451 | }); 452 | // }) 453 | 454 | }; 455 | 456 | function uploadVids(file, params, callback) { 457 | console.log(file, params); 458 | 459 | params.client 460 | .setCookie(params.cookie) 461 | .url(`https://www.manyvids.com/Upload-vids/`) 462 | .pause(2000) 463 | .chooseFile("#container > div > input", file) 464 | .getValue("#container > div > input").then(function(val) { 465 | console.log('File to Upload: ' + JSON.stringify(val)); 466 | }); 467 | } 468 | 469 | module.exports = { 470 | login: auth, 471 | getUpload: getUpload, 472 | postUpload: postUpload 473 | }; 474 | -------------------------------------------------------------------------------- /api/server.cert: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIID/zCCAuegAwIBAgIJAOnSvx74KMiPMA0GCSqGSIb3DQEBCwUAMIGVMQswCQYD 3 | VQQGEwJVUzELMAkGA1UECAwCRkwxFDASBgNVBAcMC1BvcnQgUmljaGV5MRcwFQYD 4 | VQQKDA5OZXJvIE1lZGlhIExMQzELMAkGA1UECwwCSVQxFTATBgNVBAMMDDE5Mi4x 5 | NjguMS4zODEmMCQGCSqGSIb3DQEJARYXYWlkZW5AeHh4bXVsdGltZWRpYS5jb20w 6 | HhcNMTkwNDE5MTUxODExWhcNMTkwNTE5MTUxODExWjCBlTELMAkGA1UEBhMCVVMx 7 | CzAJBgNVBAgMAkZMMRQwEgYDVQQHDAtQb3J0IFJpY2hleTEXMBUGA1UECgwOTmVy 8 | byBNZWRpYSBMTEMxCzAJBgNVBAsMAklUMRUwEwYDVQQDDAwxOTIuMTY4LjEuMzgx 9 | JjAkBgkqhkiG9w0BCQEWF2FpZGVuQHh4eG11bHRpbWVkaWEuY29tMIIBIjANBgkq 10 | hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAv1bYlRsH2PI9m8dMAcmXF2+vUwbx+1/B 11 | Lp76yWQIK/N+1bUMpHyaZBXt5bHiuAwr7qHcu+i55Z/xVqnjpiRTCOSYzIB2X9T7 12 | HcG4/eTBPtw4EQP7TLVf5cgZMVyIOeKXv1luaRrTxMm250MsVARlV5SChZpVo2lJ 13 | oR4yg1DOex62MUqNRFe0EUPj0SxrPi5WusCGbt5ZYV4jbMCRdr4UknAAVjp38s/G 14 | mkev3li64/g8hWrpFUzmfnREdhoWCMioDiGOxbT9Fg78CfrzDL5leJM5l/hqy37Q 15 | FNR5Bfoy4eiALW5m5Zr2esqa7+7a5GlrbjJwnvvL3ZFp095cj3RiHQIDAQABo1Aw 16 | TjAdBgNVHQ4EFgQUd9LNfYi454DhMjzbw7gdzkGlpn0wHwYDVR0jBBgwFoAUd9LN 17 | fYi454DhMjzbw7gdzkGlpn0wDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOC 18 | AQEAqA5MeipNQOm6+ayf58agjb55VrA4JzL1iEkALye6bHUYxY3NPO8cs+cib4WX 19 | 6z05tzAsnE8e1qGhzyp/eBzqvn0hzDJ5Sw4gjr/mxNeG5m+iJqOJlJWNbRvQbC3t 20 | uRwiDqYhSKgZf2EyP98Mz8gnBcoqiIUVRdiCsFG/vqObYO6Mzgz+4PjVT+CiYcYA 21 | NC9mGP4Z66eCbUFzIM/Qa0ypyuPQj5Ldfoz9rJf3lWEnm2wyD/ZAT2M5UR5D0T0S 22 | s9m4DaPaR5DJpsUs5BvEaSOBq0EoQoAkRrKNm7knF1g3JX5KCbkIazAvnZKIAlHb 23 | k8AHVRP+J8ZBQFMFVbGr6mzbPA== 24 | -----END CERTIFICATE----- 25 | -------------------------------------------------------------------------------- /api/server.js: -------------------------------------------------------------------------------- 1 | (function() { 2 | 'use strict'; 3 | 4 | const express = require('express'); 5 | const cors = require('cors'); 6 | const path = require('path'); 7 | const fs = require('fs'); 8 | const router = require(path.join(__dirname, 'routes/')); 9 | const https = require('https'); 10 | const app = express(); 11 | const client = require('./webdriverio/client.js').client; 12 | 13 | app.use(function(req, res, next) { 14 | res.setHeader('X-Powered-By', 'ClipNuke.com') 15 | next() 16 | }) 17 | 18 | app.use(cors()); 19 | 20 | // Connect all our routes to our application 21 | app.use('/', router); 22 | 23 | // Pretty-Print JSON 24 | app.set('json spaces', 2); 25 | 26 | https.createServer({ 27 | key: fs.readFileSync(path.join(__dirname, 'server.key')), 28 | cert: fs.readFileSync(path.join(__dirname, 'server.cert')), 29 | }, app) 30 | .listen(3000, '127.0.0.1', function() { 31 | console.log('ClipNuke Server listening on port 3000! Go to https://localhost:3000/') 32 | }) 33 | 34 | // This endpoint sends a signal to stop the server for the process refresh buttons,. 35 | app.get('/restart', function(req, res, next) { 36 | process.exit(1); 37 | }); 38 | 39 | module.exports = app; 40 | 41 | }()); 42 | -------------------------------------------------------------------------------- /api/server.key: -------------------------------------------------------------------------------- 1 | -----BEGIN PRIVATE KEY----- 2 | MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC/VtiVGwfY8j2b 3 | x0wByZcXb69TBvH7X8EunvrJZAgr837VtQykfJpkFe3lseK4DCvuody76Lnln/FW 4 | qeOmJFMI5JjMgHZf1Psdwbj95ME+3DgRA/tMtV/lyBkxXIg54pe/WW5pGtPEybbn 5 | QyxUBGVXlIKFmlWjaUmhHjKDUM57HrYxSo1EV7QRQ+PRLGs+Lla6wIZu3llhXiNs 6 | wJF2vhSScABWOnfyz8aaR6/eWLrj+DyFaukVTOZ+dER2GhYIyKgOIY7FtP0WDvwJ 7 | +vMMvmV4kzmX+GrLftAU1HkF+jLh6IAtbmblmvZ6yprv7trkaWtuMnCe+8vdkWnT 8 | 3lyPdGIdAgMBAAECggEACsvpuLAnxzQUCeA7B7bKUcY5jGPN77M9gVXzLL36QBCj 9 | TYfDyNxHEfKy080vz9bP+80iWXAOXUijI5K+h7dxAAV2IcP16f5olQtDVwA7b0KZ 10 | 30vsOC3b1WlvEnv4K9v/WArB0ihzXp1LNs1xiOQem8yDeOp2fpwITZEYpJRAsm22 11 | LMJhr3zkKuZ3fnjhhOGSDshWMMugqZn4yG9vY5zHLT47X4IPNMNZ6QcImO4+c7PW 12 | bEKaLNgBVNd0CPoGBcZORrLQ2L2wz9+Xb4Qk9Z2MoxieKVDbykpwv1TgVXpsHgoE 13 | IGZD/BQIgLNnsO7t+dpLa4Z/6qJngtZyhzcqPjJdAQKBgQDtJqUWpah7oSLLHDwl 14 | WZeyy7qZvefY2SkTO79YjaU1pLp+0tK8ZGd5JC2YxnY+bM4N/Mwz3ksW641b5uzw 15 | 4B4Bjn/IW7fqqTrItn2Bax08meCYsG/ZhuLJzUCjjN9aU/BZKtozquC2SKgEA/gC 16 | 2UBGcCDZRI+IOBrOFUOciTRdYQKBgQDOjA/Dv1HJ1Axwj0DaeD4akEs45o6PrUTR 17 | /2xlsmWE7rgYB6rVQGtwvZ3sc8JoZLr+wrMHxXaDyAOB74klugUOi71/R51uhtSG 18 | dbePsT1RQOmlVuruXhGjTSRDhNIvnBUT3/A+sn0DpBanyiOAWTrHRaeTHwEXZM78 19 | RRBVmRtiPQKBgGIV0740MiVAFkXvnajND4Mx5DHma9gyqVx9H70eiLBRO5ls1SB6 20 | XpmqLvm7S/ixw9/hKQxi6qfGMSdLscBG0eJO7+cMmFsEN34AjJRUmzkPY+eDQh+0 21 | PGS+8fczMsYHZadbo/guutZp4qQWiCOVe5Immk+CneL3YY7PGLHLxc7BAoGBALXI 22 | IUvHQyVdggFCovJkJ0xbuEiA6fFbrpkfsvgiNST0sIM9pEWBJ84WpDnpe61DEiyL 23 | kOODD5ZV33hpKAxTFoZByGqPzefrtHoOepp1hCDR/5Br2eImWmGd0A+4gwAx338Z 24 | dSjJECu3K9VKm0onvgqJrD1YaS58o4r1AbZERQyFAoGBAM93D0mrN1vpR3EVmspI 25 | GhWs7bL918k3LbDMAg8QqIo2K7joy6GqKVhfGQTLVegoKw42LmHS5eeHf+6FGc2N 26 | EchHsdDEvXy/IOhBeTwQMLDgZew8NoHvFRcmgowhHy5ZEc/tmJm1GneuUzcJp7TR 27 | xjmSh3wcNtDUlPSRXpkgypn2 28 | -----END PRIVATE KEY----- 29 | -------------------------------------------------------------------------------- /api/webdriverio/client.js: -------------------------------------------------------------------------------- 1 | const webdriverio = require('webdriverio'); 2 | const path = require('path'); 3 | 4 | /** 5 | * Initialized a new WebDriverIO Client. 6 | */ 7 | const config = require(path.join(__dirname, 'config.js')).config; 8 | var client = webdriverio.remote(config); 9 | 10 | module.exports = { 11 | client 12 | }; 13 | -------------------------------------------------------------------------------- /api/webdriverio/config.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | 3 | /** 4 | * WebDriverIO Configuration 5 | */ 6 | let debug = process.env.DEBUG; 7 | const config = { 8 | capabilities: [{ 9 | browserName: 'chrome' 10 | }], 11 | desiredCapabilities: { 12 | browserName: 'chrome', 13 | // seleniumAddress: 'http://localhost:4444/wd/hub', 14 | // 'w3c': false, 15 | chromeOptions: { 16 | binary: path.join(__dirname, '../bin/chromedriver.exe'), 17 | // binary: 'electron ' + __dirname, 18 | // 'w3c': false, 19 | args: [ 20 | 'user-agent=Mozilla/5.0 (iPhone; CPU iPhone OS 7_0 like Mac OS X; en-us) AppleWebKit/537.51.1 (KHTML, like Gecko) Version/7.0 Mobile/11A465 Safari/9537.53', 21 | 'headless', 22 | // Use --disable-gpu to avoid an error from a missing Mesa 23 | // library, as per 24 | // https://chromium.googlesource.com/chromium/src/+/lkgr/headless/README.md 25 | 'disable-gpu', 26 | 'no-sandbox', 27 | 'disable-dev-shm-usage', 28 | 'allow-insecure-localhost', 29 | ], 30 | } 31 | }, 32 | singleton: true, // Enable persistent sessions 33 | debug: true, 34 | // host: "http://localhost", 35 | // port: 4444 36 | }; 37 | 38 | module.exports = { 39 | config 40 | }; 41 | -------------------------------------------------------------------------------- /api/webdriverio/singleton.js: -------------------------------------------------------------------------------- 1 | /*** 2 | * NodeJS module that implements the single pattern. 3 | * http://en.wikipedia.org/wiki/Singleton_pattern 4 | * 5 | * The goals is to create the object: instance only one time 6 | * thus the instance is shared in the source code. 7 | * 8 | * You must be aware that there is a risk to break 9 | * the isolation principles. 10 | */ 11 | const webdriverio = require('webdriverio'); 12 | const config = require('./config.js').config; 13 | 14 | var client; 15 | if (!global.instance) { 16 | var instance = {}; 17 | instance.state = false; 18 | instance.func1 = function(state) { 19 | instance.state = state; 20 | }; 21 | instance.client = webdriverio.remote(config); 22 | global.instance = instance; 23 | } 24 | 25 | exports.instance = global.instance; 26 | -------------------------------------------------------------------------------- /bin/chromedriver.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aidenvalentine/adult-content-api/6005229cf2b7bd78512fe7cf3edbe15d65786429/bin/chromedriver.exe -------------------------------------------------------------------------------- /license.md: -------------------------------------------------------------------------------- 1 | ## License 2 | By obtaining, using and/or copying this work, you (the licensee) agree that you have read, understood, and will comply with the following terms and conditions. 3 | 4 | Permission to copy, modify, and distribute this software and its documentation, with or without modification, for any purpose and without fee or royalty is hereby granted, provided that you include the following on ALL copies of the software and documentation or portions thereof, including modifications: 5 | 6 | The full text of this NOTICE in a location viewable to users of the redistributed or derivative work. 7 | Any pre-existing intellectual property disclaimers, notices, or terms and conditions. If none exist, the W3C Software Short Notice should be included (hypertext is preferred, text is permitted) within the body of any redistributed or derivative code. 8 | Notice of any changes or modifications to the files, including the date changes were made. (We recommend you provide URIs to the location from which the code is derived.) 9 | 10 | ## Disclaimers 11 | THIS SOFTWARE AND DOCUMENTATION IS PROVIDED "AS IS," AND COPYRIGHT HOLDERS MAKE NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO, WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF THE SOFTWARE OR DOCUMENTATION WILL NOT INFRINGE ANY THIRD PARTY PATENTS, COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS. 12 | 13 | COPYRIGHT HOLDERS WILL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF ANY USE OF THE SOFTWARE OR DOCUMENTATION. 14 | 15 | The name and trademarks of copyright holders may NOT be used in advertising or publicity pertaining to the software without specific, written prior permission. Title to copyright in this software and any associated documentation will at all times remain with copyright holders. 16 | --------------------------------------------------------------------------------