1
0
Fork 0
mirror of https://github.com/openstf/stf synced 2025-10-05 02:29:26 +02:00

Support installation from URLs.

This commit is contained in:
Simo Kinnunen 2014-04-03 22:50:51 +09:00
parent 7c3b180f8d
commit 97a042a54d
4 changed files with 132 additions and 65 deletions

View file

@ -427,10 +427,15 @@ program
, 'public ip for global access'
, String
, ip())
.option('--save-dir <dir>'
, 'where to save files'
, String
, os.tmpdir())
.action(function(options) {
require('./roles/storage/temp')({
port: options.port
, publicIp: options.publicIp
, saveDir: options.saveDir
})
})

View file

@ -64,6 +64,20 @@ module.exports = function(options) {
secret: options.secret
, authUrl: options.authUrl
}))
// Proxied requests must come before any body parsers
app.post('/api/v1/resources', function(req, res) {
proxy.web(req, res, {
target: options.storageUrl
})
})
app.get('/api/v1/resources/:id', function(req, res) {
proxy.web(req, res, {
target: options.storageUrl
})
})
app.use(express.json())
app.use(express.urlencoded())
app.use(express.csrf())
@ -187,18 +201,6 @@ module.exports = function(options) {
})
})
app.post('/api/v1/resources', function(req, res) {
proxy.web(req, res, {
target: options.storageUrl
})
})
app.get('/api/v1/resources/:id', function(req, res) {
proxy.web(req, res, {
target: options.storageUrl
})
})
io.set('authorization', (function() {
var parse = Promise.promisify(express.cookieParser(options.secret))
return function(handshake, accept) {

View file

@ -1,12 +1,16 @@
var http = require('http')
var util = require('util')
var fs = require('fs')
var express = require('express')
var formidable = require('formidable')
var Promise = require('bluebird')
var ApkReader = require('adbkit-apkreader')
var request = require('request')
var temp = require('temp')
var logger = require('../../util/logger')
var requtil = require('../../util/requtil')
var Storage = require('../../util/storage')
module.exports = function(options) {
@ -19,45 +23,85 @@ module.exports = function(options) {
app.set('case sensitive routing', true)
app.set('trust proxy', true)
app.use(express.json())
app.use(express.urlencoded())
storage.on('timeout', function(id) {
log.info('Cleaning up inactive resource "%s"', id)
})
app.post('/api/v1/resources', function(req, res) {
var form = Promise.promisifyAll(new formidable.IncomingForm())
form.parseAsync(req)
.spread(function(fields, files) {
if (files.file) {
try {
var reader = ApkReader.readFile(files.file.path)
function process(file) {
log.info('Processing "%s"', file.path)
var reader = ApkReader.readFile(file.path)
var manifest = reader.readManifestSync()
var id = storage.store(files.file)
res.json(201, {
success: true
, url: util.format(
var id = storage.store(file)
return {
url: util.format(
'http://%s:%s/api/v1/resources/%s'
, options.publicIp
, options.port
, id
)
, manifest: manifest
}
}
function download(url) {
var resolver = Promise.defer()
var path = temp.path({
dir: options.saveDir
})
log.info('Downloading "%s" to "%s"', url, path)
function errorListener(err) {
resolver.reject(err)
}
function closeListener() {
resolver.resolve({
path: path
})
}
try {
var dl = request(url)
.pipe(fs.createWriteStream(path))
.on('error', errorListener)
.on('close', closeListener)
}
catch (err) {
log.error('ApkReader had an error', err.stack)
res.json(500, {
success: false
resolver.reject(err)
}
return resolver.promise.finally(function() {
dl.removeListener('error', errorListener)
dl.removeListener('end', closeListener)
})
}
app.post('/api/v1/resources', function(req, res) {
var form = Promise.promisifyAll(new formidable.IncomingForm())
form.parseAsync(req)
.spread(function(fields, files) {
if (files.file) {
return process(files.file)
}
else if (fields.url) {
return download(fields.url).then(process)
}
else {
throw new requtil.ValidationError('"file" or "url" is required')
}
})
.then(function(data) {
data.success = true
res.json(201, data)
})
.catch(requtil.ValidationError, function() {
res.json(400, {
success: false
, error: 'ValidationError'
})
}
})
.catch(function(err) {
log.error('Failed to save resource: ', err.stack)

View file

@ -1,6 +1,7 @@
module.exports = function ControlServiceFactory(
$rootScope
, $upload
, $http
, socket
, TransactionService
) {
@ -108,35 +109,50 @@ module.exports = function ControlServiceFactory(
return tx
}
function install(options) {
var app = options.manifest.application
var tx = TransactionService.create(target)
var params = {
url: options.url
}
if (app.launcherActivities.length) {
var activity = app.launcherActivities[0]
params.launchActivity = {
action: 'android.intent.action.MAIN'
, component: options.manifest.package + '/' + activity.name
, category: ['android.intent.category.LAUNCHER']
, flags: 0x10200000
}
}
socket.emit('device.install', channel, tx.channel, params)
tx.manifest = options.manifest
return tx
}
this.install = function(files) {
if (typeof files === 'string') {
return $http({
url: '/api/v1/resources'
, method: 'POST'
, data: {
url: files
}
})
.then(function(response) {
return install(response.data)
})
}
else {
return $upload.upload({
url: '/api/v1/resources'
, method: 'POST'
, file: files[0]
})
.then(function(response) {
var manifest = response.data.manifest
var app = manifest.application
var tx = TransactionService.create(target)
console.log('resp',response)
console.log(manifest)
var params = {
url: response.data.url
}
if (app.launcherActivities.length) {
var activity = app.launcherActivities[0]
params.launchActivity = {
action: 'android.intent.action.MAIN'
, component: manifest.package + '/' + activity.name
, category: ['android.intent.category.LAUNCHER']
, flags: 0x10200000
}
}
socket.emit('device.install', channel, tx.channel, params)
tx.manifest = manifest
return tx
return install(response.data)
})
}
}
this.uninstall = function(pkg) {
var tx = TransactionService.create(target)