diff --git a/Gruntfile.js b/Gruntfile.js index 55ab68f..ad9641f 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -16,6 +16,7 @@ module.exports = function (grunt) { csvreader_assets = src_dir + '/csvreader_assets', tsvreader_assets = src_dir + '/tsvreader_assets', pdfreader_assets = src_dir + '/pdfreader_assets', + tablereader_assets = src_dir + '/tablereader_assets', reader_assets_src_dir = src_dir + '/reader_assets', admin_assets_src_dir = src_dir + '/admin_assets', webviews_assets_src_dir = src_dir + '/webviews_assets'; @@ -189,6 +190,15 @@ module.exports = function (grunt) { {expand: true, cwd: 'src/templates/pages', src: ['*.hbs'], dest: admin_dist_dir} ] }, + pages_frame: { + // Target-level options + options: { + layout: 'default_frame.hbs' + }, + files: [ + {expand: true, cwd: 'src/templates/pages', src: ['*.hbs'], dest: admin_dist_dir+'/frames/'} + ] + }, login: { options: { layout: 'login.hbs' @@ -241,14 +251,38 @@ module.exports = function (grunt) { /* copy pdfreader assets to reader & admin */ { expand: true, - cwd: pdfreader_assets, src: ['lib/**','js/**'], + cwd: pdfreader_assets, src: ['js/**'], dest: reader_assets_dist_dir + '/' }, { expand: true, - cwd: pdfreader_assets, src: ['lib/**','js/**'], + cwd: pdfreader_assets, src: ['js/**'], dest: admin_assets_dist_dir + '/' }, + { + expand: true, + cwd: 'bower_components/pdfjs-dist/build/', + src: [ 'pdf.js', 'pdf.worker.js' ], + dest: reader_assets_dist_dir + '/lib/pdf.js/' + }, + { + expand: true, + cwd: 'bower_components/pdfjs-dist/build/', + src: [ 'pdf.js', 'pdf.worker.js' ], + dest: admin_assets_dist_dir + '/lib/pdf.js/' + }, + { + expand: true, + cwd: 'bower_components/pdfjs-dist/web/', + src: [ 'compatibility.js' ], + dest: reader_assets_dist_dir + '/lib/pdf.js/' + }, + { + expand: true, + cwd: 'bower_components/pdfjs-dist/web/', + src: [ 'compatibility.js' ], + dest: admin_assets_dist_dir + '/lib/pdf.js/' + }, { expand: true, cwd: 'bower_components/canvasloader/js/', @@ -400,7 +434,8 @@ module.exports = function (grunt) { './js/bootstrap-timepicker.min.js'], dest: admin_assets_dist_dir + '/lib/bootstrap-timepicker/' }, - // formbuilder + + /* copy jquery-ui */ { expand:true, cwd:'bower_components/jquery-ui/ui/minified', src: [ "jquery.ui.core.min.js", "jquery.ui.widget.min.js", "jquery.ui.mouse.min.js", @@ -408,6 +443,15 @@ module.exports = function (grunt) { "jquery.ui.droppable.min.js", "jquery.ui.sortable.min.js" ], dest: admin_assets_dist_dir + '/lib/' }, + { expand:true, cwd:'bower_components/jquery-ui/ui/minified', + src: [ "jquery.ui.core.min.js", "jquery.ui.widget.min.js", + "jquery.ui.mouse.min.js", + "jquery.ui.draggable.min.js", + "jquery.ui.droppable.min.js", + "jquery.ui.sortable.min.js" ], + dest: reader_assets_dist_dir + '/lib/' }, + + // formbuilder { src: 'bower_components/backbone-deep-model/distribution/deep-model.min.js', dest: admin_assets_dist_dir + '/lib/backbone/deep-model.min.js' }, { src: 'bower_components/backbone/backbone.js', @@ -764,7 +808,31 @@ module.exports = function (grunt) { cwd: 'bower_components/taffydb/', src: ['taffy-min.js'], dest: webviews_assets_dist_dir + '/lib' - } + }, + /* copy pivottable.js dist */ + { + expand: true, + cwd: 'bower_components/pivottable/dist/', + src: ['./**'], + dest: admin_assets_dist_dir + '/lib/pivottable/' + }, + { + expand: true, + cwd: 'bower_components/pivottable/dist/', + src: ['./**'], + dest: reader_assets_dist_dir + '/lib/pivottable/' + }, + /* copy tablereader assets to reader & admin */ + { + expand: true, + cwd: tablereader_assets, src: ['js/**'], + dest: reader_assets_dist_dir + '/' + }, + { + expand: true, + cwd: tablereader_assets, src: ['js/**'], + dest: admin_assets_dist_dir + '/' + }, ] } }, diff --git a/bower.json b/bower.json index b483e43..9da3f82 100644 --- a/bower.json +++ b/bower.json @@ -30,7 +30,7 @@ "path": "~3.24.10", "querystring": "~3.24.10", "tweenjs": "*", - "videojs": "~4.6.3", + "videojs": ">=4.6.3", "js-url": "~1.8.6", "flexslider": "*", "screenfull": "~1.2.1", @@ -42,7 +42,9 @@ "jssor-slider": "*", "bootstrap-datepicker": "~1.3.0", "canvasloader": "~0.9.1", - "bootstrap-timepicker": "~0.2.6" + "bootstrap-timepicker": "~0.2.6", + "pdfjs-dist": "~1.0.1135", + "pivottable": "*" }, "resolutions": { "font-awesome": ">=4.2.0", diff --git a/src/admin_assets/js/initS3Auth.js b/src/admin_assets/js/initS3Auth.js index e9618ba..e2571c1 100644 --- a/src/admin_assets/js/initS3Auth.js +++ b/src/admin_assets/js/initS3Auth.js @@ -95,8 +95,7 @@ else else { AWS.config.update({ - accessKeyId: s3AuthObj.accessKeyId, - secretAccessKey: s3AuthObj.secretAccessKey + credentials: new AWS.Credentials(s3AuthObj.credentials) }); initAWSS3(); } diff --git a/src/admin_assets/js/login.js b/src/admin_assets/js/login.js index 7151209..f4c5714 100644 --- a/src/admin_assets/js/login.js +++ b/src/admin_assets/js/login.js @@ -1,4 +1,68 @@ -$(function(){ +var docQuery = path.parseQuery(document.location.search.slice(1)); +// automatic login +if(docQuery.autologin) +{ + (function(){ + var credentials; + if(docQuery.credentials) + { + credentials = JSON.parse(docQuery.credentials); + var conv = { + "AccessKeyId": "accessKeyId", + "SecretAccessKey": "secretAccessKey", + "SessionToken": "sessionToken" + }; + for(var key in conv) + { + if(credentials[key]) + { + credentials[conv[key]] = credentials[key]; + delete credentials[key]; + } + } + } + else + { + credentials = { + accessKeyId: docQuery.accessKeyId, + secretAccessKey: docQuery.secretAccessKey + }; + } + if(!credentials) + return; + try { + var auth_obj = JSON.parse(storage.getItem(config.storageAuthKey)); + if(auth_obj && + (auth_obj.method == 'main' && + compareCredentials(auth_obj.credentials, credentials)) && + docQuery.rootDirectory == auth_obj.rootDirectory && + (!docQuery.selectedApp || + docQuery.selectedApp == auth_obj.selectedApp)) + { + redirectLoggedInUser(); + return; + } + } catch(e) { } + var hideit = true; + $(function(){ if(hideit) $('body').hide() }); + loginWithCredentials(credentials, + docQuery.rootDirectory, docQuery.selectedApp, + function(err) + { + if(err) + { + alert(err); + hideit = false; + $('body').show(); + return; + } + redirectLoggedInUser(); + }); + })() +} +else +{ + $(function(){ $('.form-signin').bind('submit', function(e) { e.preventDefault(); @@ -23,90 +87,23 @@ $(function(){ selectedApp = rootDirectory.substr(rds_idx + 1); rootDirectory = rootDirectory.substring(0, rds_idx); } - AWS.config.update({ - accessKeyId: accessKeyId, - secretAccessKey: secretAccessKey - }); - AWS.config.region = config.s3BucketRegion; - var s3 = new AWS.S3({ region: config.s3BucketRegion, maxRetries: 1 }), - bucket = config.s3Bucket; $('button', form).prop('disabled', true); - s3.listObjects({ - Bucket: bucket, - Prefix: rootDirectory + "/" + - (selectedApp ? selectedApp + '/' : ''), - MaxKeys: 1 - }, function(err, data) - { - function continue_job() - { - if(selectedApp) - storage.setItem(config.storageAppNameKey, - selectedApp); - $submitBtn.ladda( 'stop' ); - redirectLoggedInUser(); - } - if(err) - { - $submitBtn.ladda( 'stop' ); - alert(_("Couldn't connect to aws s3") + ": " + err); - } - else if(!data || !data.Contents || - data.Contents.length <= 0) - { - $submitBtn.ladda( 'stop' ); - alert(_("Invalid directory!")); - } - else - { - if(!storage) - alert(_("This app does not support your browser")); - else - { - var auth_obj = { - method: 'main', - accessKeyId: accessKeyId, - secretAccessKey: secretAccessKey, - rootDirectory: rootDirectory - }; - storage.type = 'local'; - var storage_t = $('#remember-me').prop('checked') ? - 'local' : 'session'; - storage.setItem('storage-type', storage_t); - - storage.type = storage_t; - var prevObj = storage.getItem(config.storageAuthKey); - if(!prevObj || prevObj.accessKeyId != accessKeyId) - clearUserStorage(); // clear user info - storage.setItem(config.storageAuthKey, JSON.stringify(auth_obj)); - if(selectedApp) - { - storage.setItem(config.singleAppModeKey, "1"); - continue_job(); - } - else - { - /* select default app before redirect! */ - s3ListDirectories(s3, { - Bucket: config.s3Bucket, - Prefix: auth_obj.rootDirectory + '/' - }, function(err, apps) - { - if(err) - { - alert(err); - return; - } - if(apps.length > 0) - selectedApp = apps[0]; - continue_job(); - }) - } - } - } - - $('button', form).prop('disabled', false); - }); + var credentials = { + accessKeyId: accessKeyId, + secretAccessKey: secretAccessKey + }; + loginWithCredentials(credentials, rootDirectory, selectedApp, + function(err) + { + $submitBtn.ladda( 'stop' ); + $('button', form).prop('disabled', false); + if(err) + { + alert(err); + return; + } + redirectLoggedInUser(); + }); return false; }); // social network authentication starts @@ -140,7 +137,8 @@ $(function(){ } return false; }); -}); + }); +} function idFedLogin(opts, cb) { /* opts_ex = { @@ -280,3 +278,90 @@ function clearUserStorage() storage.setItem(config.storageAppNameKey, ''); storage.setItem(config.singleAppModeKey, ''); } +function loginWithCredentials(credentials, rootDirectory, selectedApp, callback) +{ + AWS.config.credentials = new AWS.Credentials(credentials); + AWS.config.region = config.s3BucketRegion; + var s3 = new AWS.S3({ region: config.s3BucketRegion, maxRetries: 1 }), + bucket = config.s3Bucket; + s3.listObjects({ + Bucket: bucket, + Prefix: rootDirectory + "/" + + (selectedApp ? selectedApp + '/' : ''), + MaxKeys: 1 + }, function(err, data) + { + function continue_job() + { + if(selectedApp) + storage.setItem(config.storageAppNameKey, + selectedApp); + callback(); + } + if(err) + { + callback(_("Couldn't connect to aws s3") + ": " + err); + } + else if(!data || !data.Contents || + data.Contents.length <= 0) + { + callback(_("Invalid directory!")); + } + else + { + if(!storage) + callback(_("This app does not support your browser")); + else + { + var auth_obj = { + method: 'main', + credentials: credentials, + rootDirectory: rootDirectory + }; + storage.type = 'local'; + var storage_t = $('#remember-me').prop('checked') ? + 'local' : 'session'; + storage.setItem('storage-type', storage_t); + + storage.type = storage_t; + var prevObj = storage.getItem(config.storageAuthKey); + prevObj = prevObj ? JSON.parse(prevObj) : null; + if(!prevObj || + !(prevObj.method == 'main' && + compareCredentials(prevObj, credentials))) + clearUserStorage(); // clear user info + storage.setItem(config.storageAuthKey, JSON.stringify(auth_obj)); + if(selectedApp) + { + storage.setItem(config.singleAppModeKey, "1"); + continue_job(); + } + else + { + /* select default app before redirect! */ + s3ListDirectories(s3, { + Bucket: config.s3Bucket, + Prefix: auth_obj.rootDirectory + '/' + }, function(err, apps) + { + if(err) + { + callback(err); + return; + } + if(apps.length > 0) + selectedApp = apps[0]; + continue_job(); + }) + } + } + } + }); +} +function compareCredentials(c1, c2) +{ + return c1.accessKeyId == c2.accessKeyId && + c1.secretAccessKey == c2.secretAccessKey && + ((!c1.sessionToken && !c2.sessionToken) || + (c1.sessionToken == c2.sessionToken)); +} diff --git a/src/admin_assets/js/pages/analytics.js b/src/admin_assets/js/pages/analytics.js index 326f05a..740ea62 100644 --- a/src/admin_assets/js/pages/analytics.js +++ b/src/admin_assets/js/pages/analytics.js @@ -1,3 +1,4 @@ + var app_name = storage.getItem(config.storageAppNameKey), app_dir = get_app_dir(app_name); @@ -10,6 +11,9 @@ app_dir = get_app_dir(app_name); gapi.analytics.ready(function() { + + + awsS3Ready(function() { awsS3.getObject({ @@ -99,42 +103,79 @@ gapi.analytics.ready(function() } function setup_ga_data() { - var countryDataChart = new gapi.analytics.googleCharts.DataChart({ - query: { - ids: 'ga:' + ga_profile.id, - metrics: 'ga:sessions', - dimensions: 'ga:country', - //'start-date': '30daysAgo', - //'end-date': 'yesterday' - }, - chart: { - container: 'country-chart', - type: 'GEO', - options: { - width: '100%' - } - } - }); - countryDataChart.execute(); - - var deviceDataChart = new gapi.analytics.googleCharts.DataChart({ - query: { - ids: 'ga:' + ga_profile.id, - metrics: 'ga:sessions', - dimensions: 'ga:mobileDeviceModel', - sort: '-ga:sessions', - 'max-results': 6 - }, - chart: { - container: 'device-chart', - type: 'PIE', - options: { - width: '100%' - } - } - }); - deviceDataChart.execute(); + + + + var report = new gapi.analytics.report.Data({ + query: { + ids: 'ga:' + ga_profile.id, + metrics: 'ga:totalEvents', + 'start-date':'2005-01-01', + dimensions: 'ga:eventLabel,ga:yearMonth,ga:operatingSystem', + filters: 'ga:eventAction=@ucceeded', + 'max-results':10000 + } + }); + report.on('success', function(response) { + console.log(response); + var data = response.rows; + var publications = []; + data.forEach(function(d, i) { + parts = d[0].split('?') + d.filePath= parts[0]; //Remove args + console.log(d.filePath); + parts2 = (d.filePath).split('/'); + if (parts2.length>1){ + + d.folderName = parts2[parts2.length-2]; + d.fileNameAndExtension = parts2[parts2.length-1]; + parts3 = (d.fileNameAndExtension).split('.'); + d.fileName = parts3[0]; + d.fileExtension = parts3[1]; + //Publications are inside directories have the pdf extension + if (d.fileExtension=='pdf'){ + var obj = {}; + obj.Publication= d.folderName; + obj.YearMonth = d[1] + obj.OS = d[2] + obj.Qty = +d[3]; + if (d.fileName.lastIndexOf('_') == d.fileName.length - 1) obj.Type='Paid';//Paid publications have a file name ending with _ + else obj.Type='Free'; + publications.push(obj); + } + } + }); + + + + //console.log(publications); + + var sum = $.pivotUtilities.aggregatorTemplates.sum; + var numberFormat = $.pivotUtilities.numberFormat; + var intFormat = numberFormat({digitsAfterDecimal: 0}); + + $("#pivotstable").pivotUI( + publications, + { + rows: ["Publication"], + cols: ["Type"], + aggregators: {"Quantity":function() { return sum(intFormat)(["Qty"]) }}, + hiddenAttributes: ["Qty"] + } + + + ); + + + + + }); + + + report.execute(); + + } }); }); @@ -197,3 +238,5 @@ function responseCompleteProcessGetItems(cb, noerror) } }; } + +; diff --git a/src/admin_assets/js/pages/authorizations.js b/src/admin_assets/js/pages/authorizations.js new file mode 100644 index 0000000..142b360 --- /dev/null +++ b/src/admin_assets/js/pages/authorizations.js @@ -0,0 +1,158 @@ +$(function() +{ + var app_name = storage.getItem(config.storageAppNameKey), + app_dir = get_app_dir(app_name), + auth_key = app_dir + '/APP_/Uploads/authorizations_.plist', + oauth_origin = 'http://localhost/', + oauth_url = oauth_origin+'/php/admin/oauth.php'; + if(!app_name) + return; + + awsS3Ready(start); + function start() + { + start_request_for_auth_status(); + $('#auth-gen').click(function() + { + $('#auth-status').text('Generating refresh token'); + generate_refresh_token(function(err, refreshToken) + { + if(err) + return notifyUserError(err); + if(!refreshToken) + { + $('#auth-status').text('No refresh token available!'); + return; + } + $('#auth-status').text('Storing refresh token'); + request_auth_save({ + refresh_token: refreshToken + }, function(err) + { + if(err) + { + notifyUserError(err); + $('#auth-status').text(''); + return; + } + $('#auth-status').text('Refresh token is available!'); + }); + }); + return false; + }); + } + + function start_request_for_auth_status() + { + $('#auth-status').text('Checking authorization status'); + request_auth(function(err, obj) + { + if(err) + { + handleAWSS3Error(err); + $('#auth-status').text(''); + return; + } + if(obj.refresh_token) + { + $('#auth-status').text('Refresh token is available!'); + } + else + { + $('#auth-status').text('Refresh token does not exists!'); + } + }); + } + function request_auth(callback) + { + awsS3.getObject({ + Bucket: config.s3Bucket, + Key: auth_key + }, function(err, res) + { + if(err && err.code != 'NoSuchKey') + { + callback(err); + return; + } + try { + var obj = res ? $.plist($.parseXML(res.Body.toString())) : {}; + callback(undefined, obj); + } catch(err2) { + callback('Error parsing: ' + err2); + } + }); + } + + function request_auth_save(obj, callback) + { + var body = $.plist('toString', obj); + awsS3.putObject({ + Bucket: config.s3Bucket, + Key: auth_key, + Body: body, + CacheControl: 'must-revalidate, max-age=0' + }, function(err) + { + callback && callback(err); + }); + } + + var authWin, authInterval, authCallback; + + if(window.addEventListener) + window.addEventListener('message', window_on_message, false); + else if(window.attachEvent) + window.attachEvent('onmessage', window_on_message); + + function generate_refresh_token(callback) + { + authWin = window.open(oauth_url, oauth_url, + 'resizable=yes,scrollbars=yes,' + + 'width=640,height=480'); + if(authInterval !== undefined) + clearInterval(authInterval); + authInterval = setInterval(ask_win_authorized, 100); + authCallback = function() + { + $.ajax({ + url: oauth_url + '?' + querystring.stringify({ + action: 'get', + key: 'refresh_token' + }), + xhrFields: { + withCredentials: true + }, + success: function(value) + { + callback(undefined, value); + }, + error: function(xhr, a2, err_text) + { + callback(sprintf(_("Couldn't generate access token: %s"), + err_text)) + } + }); + } + } + + function ask_win_authorized() + { + if(authWin) + authWin.postMessage('isAuthorized', oauth_origin); + } + function window_on_message(event) + { + if(event.data == 'authorized') + { + authWin.close(); + authCallback(); + if(authInterval !== undefined) + { + clearInterval(authInterval); + authInterval = undefined; + } + } + } + +}); diff --git a/src/admin_assets/js/pages/issues.js b/src/admin_assets/js/pages/issues.js new file mode 100644 index 0000000..4438814 --- /dev/null +++ b/src/admin_assets/js/pages/issues.js @@ -0,0 +1,945 @@ +var appName = storage.getItem(config.storageAppNameKey), +appDir = get_app_dir(appName), +doc_query = querystring.parse(get_url_query(document.location+'')), +pubName = doc_query.wapublication || '', +pubDir = pubName ? appDir + '/' + pubName : appDir, +magazinesFn = pubName ? pubName + '.plist' : 'Magazines.plist'; +$(function() { + function workOnAwsS3() + { + formDisplay(); + $issDlg.find('.fileinput').each(initUploadEl); + updateIssTable(function() + { + $('#page-loading-indicator2').fadeOut(); + }); + } + var $issTable = $(".issueDataTable"), + issuesTable = $issTable.dataTable({ + "aaSorting": [[ 0, "desc" ]] + }), + $issDlg = $('#issModal'); + + activeInactiveEvents($issTable); + if(!appName) + return; + + awsS3Ready(workOnAwsS3); + + + $issDlg.find('.svgedit-btn').bind('click', function() + { + var iss = $issDlg.find('input[name=FolderName]').val(), + filename = issDlgEvalAttr($(this).data('filename')); + if(filename) + { + window.open('svgedit.html?' + path.stringifyQuery({ + app: appName, + filename: iss + '/' + filename + }), '_blank'); + return false; + } + }); + $issDlg.find('.pdfannotedit-btn').bind('click', function() + { + var iss = $issDlg.find('input[name=FolderName]').val(), + filename = issDlgEvalAttr($(this).data('filename')); + if(filename) + { + window.open('pdf-annotation-editor.html?' + + path.stringifyQuery({ + waurl: pubDir + '/' + iss + '/' + filename + }), '_blank'); + return false; + } + }); + + $("#asset-uploader").pluploadQueue({ + // General settings + runtimes: 'html5', + url: 'https://' + config.s3Bucket + '.s3.amazonaws.com', + // Rename files by clicking on their titles + rename: true, + + // Sort files + sortable: true, + + // Enable ability to drag'n'drop files onto the widget (currently only HTML5 supports that) + dragdrop: true, + + // Views to activate + views: { + list: true, + thumbs: true, // Show thumbs + active: 'thumbs' + }, + + multiple_queues: true + }); + var asset_uploader = $("#asset-uploader").pluploadQueue(); + + if(s3AuthObj.type == 'idFed') + { + asset_uploader.unbind('UploadFile'); + asset_uploader.bind('UploadFile', function(up, file) + { + var filename = file.target_name || file.name; + function onCancelUpload() + { + if(xhr) + xhr.abort(); + } + function unbindEvents() + { + up.unbind('CancelUpload', onCancelUpload) + } + up.bind('CancelUpload', onCancelUpload); + var iss = $issDlg.find('input[name=FolderName]').val(), + asset_dir = $("#asset-uploader").data('dir'), + dir = pubDir + '/' + iss + (asset_dir ? '/' + asset_dir : ''), + xhr, + request = awsS3.putObject({ + Bucket: config.s3Bucket, + Key: dir + '/' + filename, + Body: file.getNative() + }, function(err, res) + { + unbindEvents(); + if(err) + { + console.error(err); + up.trigger('Error', { + code : plupload.HTTP_ERROR, + message : plupload.translate('HTTP Error.'), + file : file, + response: err+'', + status: xhr ? xhr.status : _('Unknown'), + responseHeaders: + xhr ? xhr.getAllResponseHeaders() : {} + }); + return; + } + file.loaded = file.size; + up.trigger('UploadProgress', file); + + file.status = plupload.DONE; + up.trigger('FileUploaded', file, { + response: 'success', + status: 200, + responseHeaders: {} + }); + }); + xhr = request.httpRequest.stream; + if(xhr && xhr.upload) + $(xhr.upload).on('progress', function(ev) + { + ev = ev.originalEvent; + file.loaded = ev.loaded; + up.trigger('UploadProgress', file); + }); + }); + } + else + { + asset_uploader.bind("BeforeUpload", function(up, file) { + var params = asset_uploader.settings.multipart_params; + params.key = $("#asset-uploader").data('current_dir') + file.name; + params.Filename = file.name; + }); + } + function setPLUploadInfoForIss(iss) + { + var d = new Date(new Date().getTime() + (60 * 60 * 1000)), + asset_dir = $("#asset-uploader").data('dir'), + dir = pubDir + '/' + iss + '/' + (asset_dir ? asset_dir + '/' : ''), + policy = { + "expiration": d.toISOString(), + "conditions": [ + {"bucket": config.s3Bucket}, + ["starts-with", "$key", dir], + {"acl": "private"}, + ["starts-with", "$Content-Type", ""], + ["starts-with", "$name", ""], + ["starts-with", "$Filename", ""], + ["starts-with", "$success_action_status", ""] + ] + }, + policy_str = CryptoJS.enc.Base64.stringify( + CryptoJS.enc.Utf8.parse(JSON.stringify(policy))), + signature = CryptoJS.HmacSHA1(policy_str, + s3AuthObj.credentials.secretAccessKey) + .toString(CryptoJS.enc.Base64); + var post = { + acl: 'private', + AWSAccessKeyId: s3AuthObj.credentials.accessKeyId, + policy: policy_str, + signature: signature, + 'Content-Type': '$Content-Type', + success_action_status: '201' + }; + $("#asset-uploader").data('current_dir', dir); + asset_uploader.setOption('multipart_params', post); + asset_uploader.splice(0, asset_uploader.files.length); + } + function uploadElEvalFilename(el, action) + { + var iss = $issDlg.data('issObj'), + $this = $(el), + ext = el.files && el.files.length > 0 ? + path.fileExtension(el.files[0].name) : ''; + if(iss) + { + // use existing extension + // if it's there + if($this.hasClass('paidfileupload')) + ext = (action == 'delete') ? iss.paid_ext || ext : + ext || iss.paid_ext; + else if($this.hasClass('freefileupload')) + ext = (action == 'delete') ? iss.free_ext || ext : + ext || iss.free_ext; + } + return issDlgEvalAttr($this.attr('name'), { fileext: ext }); + } + function uploadFileUpdate($upload) + { + $upload.find('input[type=file]').each(function() + { + var file = uploadElEvalFilename(this), + extensions = [ 'pdf', 'svg' ]; + for(var i = 0, l = extensions.length; i < l; ++i) + { + var ext = extensions[i]; + $upload.toggleClass('fileinput-' + ext, + (path.fileExtension(file) == '.' + ext)); + } + }); + } + function uploadFileUpdateExtension(inp) + { + var iss = $issDlg.data('issObj') || {}, + $inp = $(inp), + ext = inp.files && inp.files.length > 0 ? + path.fileExtension(inp.files[0].name) : ''; + if($inp.hasClass('paidfileupload')) + iss.paid_ext = ext; + else if($inp.hasClass('freefileupload')) + iss.free_ext = ext; + $issDlg.data('issObj', iss); + } + function initUploadEl() + { + var $upload = $(this), + $file = $upload.find('input[type=file]'); + this._s3Upload = s3UploadInit($upload, { + s3: awsS3, + type: $file.data('type') || 'file', + Bucket: config.s3Bucket, + removeBeforeChange: issDlgAttrHasVar($file.attr('name'), 'fileext'), + Key: function(action) + { + var title = $issDlg.find('input[name=FolderName]').val(), + file = uploadElEvalFilename(this, action); + return pubDir + '/' + title + '/' + file; + }, + signExpires: function() + { + return awsExpireReverse(config.awsExpireReverseInHours); + }, + onUploadSuccess: function() + { + issDlgUpdated = true; + uploadFileUpdateExtension(this); + // this method should update file ui + uploadFileUpdate($upload) + }, + onRemoveSuccess: function() + { + issDlgUpdated = true; + uploadFileUpdateExtension(this); + // this method should update file ui + uploadFileUpdate($upload) + }, + onFileExistCheck: function(exists) + { + if($(this).hasClass('paidfileupload')) + { + $issDlg.find('input[name=Type]').each(function() + { + if(exists) + this.checked = (this.value == 'Paid'); + else + this.checked = (this.value != 'Paid'); + }); + issDlgUpdateType(); + } + }, + checkBeforeUpload: function(inp_el, file, cb) + { + if($(inp_el).data('type') == 'Image') + { + makeImageFromFile(file, function(err, image) + { + if(err) + return notifyUserError(err); + var m = validateImageSizeByElementAttrs(inp_el, image); + cb(!m); + if(m) + notifyUserError(m); + }); + } + else + { + cb(true); + } + }, + onerror: handleAWSS3Error, + loadnow: false + }); + } + var issDlgUpdated; + $issDlg.on('hidden.bs.modal', function() + { + var iss = $issDlg.data('issObj'); + if(issDlgUpdated) + { + location.reload(); + return; + } + // remove update info + $issDlg.data('issObj', null) + .removeClass('update-iss-dlg') + .toggleClass('new-iss-dlg', true); + $issDlg.find('input[type=text]').each(function() + { + $(this).val(''); + }); + $issDlg.find('.fileinput').each(function() + { + var $this = $(this); + $this.find('input[type=file]').val(''); + $this.toggleClass('fileinput-new', true) + .removeClass('fileinput-exists'); + $this.find('.fileinput-preview img').prop('src', '') + .remove(); + }); + + asset_uploader.stop(); + }); + var illegalIsss = [ "AAD", "APP__", "APP_", "APP_", "APW_" ]; + $issDlg.find('.set-title-btn').click(function() + { + var $this = $(this); + if($this.data('isLoading') || !awsS3) + return false; + var $title_inp = $issDlg.find('input[name=FolderName]'), + title_val = $title_inp.val(); + if(!title_val) + return false; + var allowed_pattrn = /^[a-z0-9\-_]+$/; + if(illegalIsss.indexOf(title_val) >= 0 || + !allowed_pattrn.test(title_val)) + { + notifyUserError(_('Invalid issue name!')); + return false; + } + $this.ladda({}).ladda('start').data('isLoading', true); + $title_inp.prop('disabled', true); + s3ObjectExists(awsS3, { + Bucket: config.s3Bucket, + Prefix: pubDir + '/' + title_val + '/' + }, function(err, exists) + { + $this.ladda('stop').data('isLoading', false); + if(err) + { + handleAWSS3Error(err); + return; + } + if(!exists) + { + $(this).parent().hide(); + $issDlg.find('.iss-body-form').show(); + if(s3AuthObj.type != 'idFed') + setPLUploadInfoForIss(title_val); + } + else + { + $title_inp.prop('disabled', false); + notifyUserError(_('Folder exists!')); + } + }); + return false; + }); + $issDlg.on('show.bs.modal', function() + { + issDlgUpdated = false; + var iss = $issDlg.data('issObj'), + type = 'Free'; + $issDlg.find('.uufile').remove(); + $issDlg.find('input[type=file]').prop('disabled', false); + $issDlg.find('.fileinput').each(function() + { + uploadFileUpdate($(this)) + }); + if(iss) + { + type = ''; + var iss_name = iss.FileName; + $issDlg.find('.set-title-btn').parent().hide(); + $issDlg.find('input[name=FolderName]').prop('disabled', true); + $issDlg.find('.iss-body-form').show(); + $issDlg.find('.fileinput').each(function() + { + var $upload = $(this), + inp = $upload.find('input[type=file]')[0]; + if(this._s3Upload) + this._s3Upload.reload(); + if(inp) + { + // fileinput download-btn ready + $upload.find('.download-btn').each(function() + { + var title = + $issDlg.find('input[name=FolderName]').val(), + file = uploadElEvalFilename(inp), + a_tag = this; + awsS3.getSignedUrl('getObject', { + Bucket: config.s3Bucket, + Key: pubDir + '/' + title + '/' + file, + Expires: awsExpireReverse(config.awsExpireReverseInHours) + }, function(err, url) + { + a_tag.href = !err && url ? url : ''; + }) + }); + } + }); + if(s3AuthObj.type != 'idFed') + setPLUploadInfoForIss(iss_name); + + // list uploaded elements and add them to list + var issDir = pubDir + '/' + iss_name + '/', + excluded_files = [ + iss_name + (iss.free_ext || ''), + iss_name + '_' + (iss.paid_ext || ''), + iss_name + '.png', + iss_name + '_newsstand.png' + ]; + s3ListAllObjects(awsS3, { + Bucket: config.s3Bucket, + Prefix: issDir + }, function(err, res) + { + if(err) + { + handleAWSS3Error(err); + return; + } + var contents = res.Contents; + for(var i = 0, l = contents.length; i < l; ++i) + { + var key = contents[i].Key, + fn = key.substr(issDir.length).replace('*', '\\*'); + if(fn && excluded_files.indexOf(fn) == -1) + insertUploadItem(fn, { class_name: 'uufile' }); + } + }); + } + else + { + $issDlg.find('input[name=FolderName]').prop('disabled', false); + $issDlg.find('.set-title-btn').parent().show(); + $issDlg.find('.iss-body-form').hide(); + } + $issDlg.find('input[name=Type]').each(function() + { + if(this.value == type) + this.checked = true; + else + this.checked = false; + }); + issDlgUpdateType(); + }); + function issDlgEvalAttr(s, vars) + { + s = s+''; + vars = $.extend(false, getObjectOfForm($issDlg), vars); + for(var i in vars) + { + var name = '*'+i+'*', + val = vars[i]; + for(var n = 0, idx; (idx = s.indexOf(name, n)) >= 0; + n = idx + name.length) + { + if(idx == 0 || s[idx-1] != '\\') + s = s.substr(0, idx) + val + s.substr(idx + name.length); + } + } + return s.replace('\\*', '*'); + } + function issDlgAttrHasVar(s, vr) + { + var idx = s.indexOf('*'+vr+'*'); + return idx == 0 || (idx > 0 && s[idx-1] != '\\'); + } + $issDlg.find('input[name=Type]').on('change', issDlgUpdateType); + function issDlgUpdateType() + { + var paid_elem = $issDlg.find('.paid-elem'), + paid_radio = $issDlg.find('input[name=Type]').filter('[value=Paid]'); + if(paid_radio.prop('checked')) + paid_elem.show(); + else + paid_elem.hide(); + } + var img_check_pttrn = /\.(jpe?g|png|gif)$/i; + function insertUploadItem(key, opts) + { + opts = opts || {}; + var class_name = opts.class_name ? ' ' + opts.class_name : '', + isImg = img_check_pttrn.test(key), + uploadLI = $('
  • \ +
    \ + \ +
    \ +
    \ +
    ' + + (isImg ? '
    ' : '') + + '
    \ + '+_('Select file')+''+_('Change')+'\ + '+_('Remove')+'\ +
    \ +
    \ +
    \ +
    \ +
  • ').appendTo($issDlg.find('.upload-list')); + var el = uploadLI.find('.fileinput')[0]; + initUploadEl.call(el); + if(el._s3Upload) + el._s3Upload.reload(); + } + + + function updateIssTable(callback) + { + s3ListAllObjects(awsS3, { + Bucket: config.s3Bucket, + Prefix: pubDir + '/', + Delimiter: '/' + }, + function(error, apps) { + + awsS3.getObject({ + Bucket: config.s3Bucket, + Key: pubDir+'/'+magazinesFn + }, function(err, activated) { + var appsList = apps.CommonPrefixes, + activeList; + try { + activeList = $.plist($.parseXML(activated.Body.toString())); + }catch(e) { + activeList = []; + } + var activeListLength = activeList.length; + + var rowsList = []; + var temp = {}; + var count = 0; + + for(var i = 0; i < appsList.length; ++i) { + + //--------------------------------------------------- + // We have 3 unwanted folders... + // ignore them and don't show them on the list + //--------------------------------------------------- + + if (isolateFolderName(appsList[i].Prefix) == "AAD" || + isolateFolderName(appsList[i].Prefix) == "APP__" || + isolateFolderName(appsList[i].Prefix) == "APP_" || + isolateFolderName(appsList[i].Prefix) == "APP_" || + isolateFolderName(appsList[i].Prefix) == "APW_") { + continue; + } + + //--------------------------------------------------- + // Prepear a single row object with default value + //--------------------------------------------------- + + temp[count] = { + FileName: isolateFolderName(appsList[i].Prefix), + FolderName: isolateFolderName(appsList[i].Prefix), + Title: "", + Subtitle: "", + status: "inactive", + statusBtn: ""+_("Inactive")+"", + id: 0 + } + for(var j = 0; j < activeListLength; ++j) { + + //--------------------------------------------------- + // There sometimes undefined keys is the object... + // it cause because of inactive publications... + // it's shouldn't happen, but we do taking + // care of it, so the front end user wont have any + // errors... jus in case... + //--------------------------------------------------- + + /*if (activeList[j] == undefined) { + continue; + }*/ + + //--------------------------------------------------- + // Does the folder name fit each other? + // if so update this publication title, subtitle + // and status + //--------------------------------------------------- + + if (isolateFolderName2(activeList[j].FileName) == temp[count].FileName || + isolateFolderName3(activeList[j].FileName) == temp[count].FileName) { + temp[count].Title = activeList[j].Title; + temp[count].Subtitle = activeList[j].Subtitle; + temp[count].status = "active"; + temp[count].statusBtn = ""+_("Active")+""; + temp[count].id = j; + added = true; + break; + } + } + + rowsList.push(temp[count]); + count++; + } + function getIssByRowId(id) + { + var pttrn = /row_([0-9]+)/, + match = pttrn.exec(id); + if(match) + { + var index = parseInt(match[1]) + if(index >= 0) + return rowsList[index]; + } + } + function issTRClick() + { + var $this = $(this), + item = getIssByRowId(this.id); + if(!item) + return; + awsS3.listObjects({ + Bucket: config.s3Bucket, + Prefix: pubDir + '/' + item.FolderName + '/' + + item.FolderName + }, function(err, res) + { + if(err) + { + handleAWSS3Error(err); + return; + } + function getKeySub(item) + { + return item.Key.substr(prefLen); + } + var prefLen = res.Prefix.length, + free = startsWith(res.Contents, '.', getKeySub), + paid = startsWith(res.Contents, '_.', getKeySub); + item = $.extend(false, {}, item); + + item.free_ext = free.length > 0 ? + free[0].Key.substr(prefLen) : null; + item.paid_ext = paid.length > 0 ? + paid[0].Key.substr(prefLen + 1) : null; + + $issDlg.find('input[type=text]') + .each(function() + { + var $this = $(this), + name = $this.attr('name'); + for(var key in item) + if(name == key) + { + $this.val(item[key]); + break; + } + }); + $issDlg.data('issObj', item) + .removeClass('new-iss-dlg') + .toggleClass('update-iss-dlg', true) + .modal('show'); + }); + return false; + } + //--------------------------------------------------- + // Add the rows to the table + //--------------------------------------------------- + + for(var i = 0; i < rowsList.length; ++i) { + addRowToTable(i, rowsList[i], issuesTable); + } + + //--------------------------------------------------- + // Apply events for the active/inactive buttons + //--------------------------------------------------- + + + $issTable.on('click', 'tbody > tr', issTRClick) + + callback && callback(); + }); + }); + } + function isolateFolderName(name) { + return name.replace(pubDir + '/', "").replace("/", ""); + } + + function isolateFolderName2(name) { + return name.substring( name.indexOf("/")+1, name.length-5); + } + + function isolateFolderName3(name) { + return name.substring( name.indexOf("/")+1, name.length-4); + } + +}); + +function formDisplay() { + $("input[name='folderName']").bind("keyup", function() { + $(".hiddenFields").show(); + }); +} + +function activeInactiveEvents(issuesTable) { + + issuesTable.on("click", "a.btnActive", {}, function(e) { + e.preventDefault(); + var obj = $(this); + activeIssue(obj, issuesTable); + return false; + }); + + issuesTable.on("click", "a.btnInactive", {}, function(e) { + e.preventDefault(); + var obj = $(this); + inactiveIssue(obj, issuesTable); + return false; + }); +} + +function activeIssue(obj, issuesTable) { + var some_html = '
    ' + + ' ' + + '
    ' + + ' ' + + '
    ' + + '
    '; + some_html += '
    ' + + ' ' + + '
    ' + + ' ' + + '
    ' + + '
    '; + + bootbox.dialog({ + message: some_html, + title: "Confirmation", + className: "littleModal", + buttons: { + success: { + label: "Confirm", + className: "btn-success", + callback: function() { + activeServerRequest(obj, issuesTable); + } + }, + danger: { + label: "Cancel", + className: "btn-danger", + callback: function() {} + } + } + }); +} + +function inactiveIssue(obj, issuesTable) { + bootbox.dialog({ + message: "Are you sure you want to inactive this issue?", + title: "Confirmation", + className: "littleModal", + buttons: { + success: { + label: "Confirm", + className: "btn-success", + callback: function() { + inactiveServerRequest(obj, issuesTable); + } + }, + danger: { + label: "Cancel", + className: "btn-danger", + callback: function() {} + } + } + }); +} +function is_paid_iss(filename, cb) +{ + s3ObjectExists(awsS3, { + Bucket: config.s3Bucket, + Key: pubDir + '/' + filename + '/' + filename + '_.pdf' + }, cb); +} +function activeServerRequest(obj, issuesTable) { + + var pTitle = $("input[name='issTitleInput']").val(); + var pSubtitle = $("input[name='issSubtitleInput']").val(); + + awsS3.getObject({ + Bucket: window.config.s3Bucket, + Key: pubDir+'/' + magazinesFn + }, function(err, activated) { + //var activeList = PlistParser.parse($.parseXML(activated.Body.toString())); + var activeList; + try { + activeList = $.plist($.parseXML(activated.Body.toString())) || []; + }catch(e) { + activeList = []; + } + is_paid_iss(obj.data('filename'), function(err, is_paid) + { + if(err) + return handleAWSS3Error(err); + var iss = { + FileName: obj.data("filename") + "/" + obj.data("filename") + + (is_paid ? '_' : '') + ".pdf", + Title: pTitle, + Subtitle: pSubtitle + }; + insertIssInList(iss, activeList); + + var body = $.plist('toString', activeList); + + + var params = { + Bucket: config.s3Bucket, // required + Key: pubDir+'/' + magazinesFn, + //Body: PlistParser.toPlist(activeList) + Body: body + }; + awsS3.putObject(params, function(err, data) { + if (err) { + return handleAWSS3Error(err); + } else { + //obj.addClass("btnInactive").addClass("btn-danger").removeClass("btnActive").removeClass("btn-success").html("Inactive").data("id", activeListLength); + //issuesTable.fnGetPosition( obj.parents('tr').closest('.ttitle')[0]).html(pTitle); + //issuesTable.fnGetPosition( obj.parents('tr').closest('.tsubtitle')[0]).html(pSubtitle); + location.reload(); + } + }); + }); + }); +} + +function inactiveServerRequest(obj, issuesTable) { + + awsS3.getObject({ + Bucket: window.config.s3Bucket, + Key: pubDir+'/' + magazinesFn + }, function(err, activated) { + + var tmp = obj.data('filename'), + activeList; + try { + activeList = $.plist($.parseXML(activated.Body.toString())); + }catch(e) { + activeList = []; + } + var filenames = [ + tmp + '/' + tmp + '_.pdf', + tmp + '/' + tmp + '.pdf' + ]; + + for(var i = 0; i < activeList.length; ) + if(filenames.indexOf(activeList[i].FileName) != -1) + activeList.splice(i, 1); + else + i++; + var body = $.plist('toString', activeList); + + //var rowIndex = issuesTable.fnGetPosition( obj.closest('tr')[0] ); + //issuesTable.fnDeleteRow(rowIndex); + + var params = { + Bucket: window.config.s3Bucket, // required + Key: pubDir+'/' + magazinesFn, + //Body: PlistParser.toPlist(activeList) + Body: cleanKeys($.plist('toString', activeList)) + }; + window.awsS3.putObject(params, function(err, data) { + if (err) { + alert(); + } else { + //obj.removeClass("btnInactive").removeClass("btn-danger").addClass("btnActive").addClass("btn-success").html("Active").data("id", 0); + //issuesTable.fnGetPosition( obj.parents('tr').closest('.ttitle')[0]).html(""); + //issuesTable.fnGetPosition( obj.parents('tr').closest('.tsubtitle')[0]).html(""); + location.reload(); + } + }); + }); +} + +function addRowToTable(index, data, issuesTable) { + issuesTable.fnAddData( { + 'DT_RowId': 'row_' + index, + '0': data.FileName, + '1': "" + data.Title + "", + '2': "" + data.Subtitle + "", + '3': data.statusBtn + }); +} + + +function deleteFromObject(obj, deleteValue) { + var objToArray = $.map(obj, function(value, index) { + return [value]; + }); + + for (var i = 0; i < objToArray.length; ++i) { + if (objToArray[i] == deleteValue) { + objToArray.splice(i, 1); + i--; + } + } + + return ArrayToObject(objToArray); +} + +function ArrayToObject(arr) { + var rv = {}; + for (var i = 0; i < arr.length; ++i) + rv[i] = arr[i]; + return rv; +} + +function cleanKeys(obj) { + //return obj.replace("\\d+\<\/key\>\n\", ""); + return obj.replace(/\n\\d+\<\/key\>\n\/g, "\n"); +} + +function insertIssInList(iss, list) +{ + var issfn = iss.FileName; + // replace issues or add it + for(var i = 0, l = list.length; i < l; ) + { + var item = list[i]; + if(item && item.FileName == issfn) + list.splice(i, 1); + else + i += 1; + } + list.unshift(iss); +} diff --git a/src/admin_assets/js/pages/pdf-annotation-editor.js b/src/admin_assets/js/pages/pdf-annotation-editor.js index c6b8704..554a661 100644 --- a/src/admin_assets/js/pages/pdf-annotation-editor.js +++ b/src/admin_assets/js/pages/pdf-annotation-editor.js @@ -4,7 +4,7 @@ app_dir = get_app_dir(app_name), doc_query = querystring.parse(get_url_query(document.location+'')), pdf_url = doc_query ? doc_query.waurl : null, s3_key, external_b = doc_query ? typeof doc_query.external != 'undefined' : null, -pdf_url_dir, annots_key, update_header_fn; +pdf_url_dir, annots_key, annots_fn, update_header_fn; $(function(){ @@ -23,8 +23,8 @@ $(function(){ { setTimeout(function() { - annots_key = path.dirname(pdf_url) + '/' + - path.basename(pdf_url, path.extname(pdf_url)) + '_updates.plist'; + annots_fn = path.basename(pdf_url, path.extname(pdf_url)) + '_updates.plist'; + annots_key = path.dirname(pdf_url) + '/' + annots_fn; var saved_data = localStorage.getItem(annots_key); if(saved_data) { @@ -196,7 +196,7 @@ $(function(){ Bucket: config.s3Bucket, Key: s3_key, Metadata: { - update: annots_key + update: annots_fn } }, function(err, res) { @@ -307,8 +307,10 @@ $(function(){ if(!hasChanged(annot)) continue; var annot_data = { - Action: annot.remove ? 'Remove' : 'Add' + Action: annot.remove ? 'Remove' : (annot.add ? 'Add' : 'Edit') }; + if(annot_data.Action != 'Add') + annot_data.IndexAtPage = annot.IndexAtPage; if(annot.id) annot_data.ID = annot.id; pres.push(annot_data); @@ -522,8 +524,14 @@ $(function(){ { var cdata = $.extend(true, {}, data); cdata.pdf_data = data; + cdata.IndexAtPage = i; add_annot(cdata); } + else + { + annot.pdf_data = data; + annot.IndexAtPage = i; + } } } }); @@ -603,6 +611,7 @@ $(function(){ var annots = annotations['p' + page.index]; el = annot_editor_link_create(data, page); data.id = genRandId(); + data.add = true; annots.push(data); $links_div.append(el); data.element = el; diff --git a/src/admin_assets/js/pages/pivots.js b/src/admin_assets/js/pages/pivots.js new file mode 100644 index 0000000..f663002 --- /dev/null +++ b/src/admin_assets/js/pages/pivots.js @@ -0,0 +1,28 @@ +$(function(){ + + var app_name = storage.getItem(config.storageAppNameKey), + app_dir = get_app_dir(app_name); + + awsS3Ready(start); + + function start() + { + awsS3.getSignedUrl('getObject', { + Bucket: config.s3Bucket, + Key: app_dir + '/APP_/REPORTS/publications_.csv', + Expires: awsExpireReverse(config.awsExpireReverseInHours) + }, function(err, table_url) + { + if(err) + return notifyUserError(err); + var tableReader = new TableReader({ + element: document.getElementById('pivotstable') + }); + tableReader.load(table_url, function(err) + { + + }); + }); + } + +}); diff --git a/src/admin_assets/js/pages/preview.js b/src/admin_assets/js/pages/preview.js index b570566..336332a 100644 --- a/src/admin_assets/js/pages/preview.js +++ b/src/admin_assets/js/pages/preview.js @@ -17,7 +17,17 @@ $(function() if(err) return notifyUserError("You should setup app first! Click Here!"); $('#preview-content').show(); - var setup_obj = res ? $.plist($.parseXML(res.Body.toString())) : {}; + var setup_obj = res ? $.plist($.parseXML(res.Body.toString())) : {}, + base_url = '//reader.librelio.com', + frame_src = base_url + '?' + querystring.stringify({ + wapublisher: s3AuthObj.rootDirectory, + waapp: app_name + }), + frame_src_html5 = base_url + '?' + querystring.stringify({ + wapublisher: s3AuthObj.rootDirectory, + waapp: app_name, + waversion: 'html5' + }); // set app active state function set_toggle_name() { @@ -48,25 +58,25 @@ $(function() $this.prop('disabled', false); set_toggle_name.call($this); if(!err) - reader.prop('src', reader.prop('src')); + { + if(setup_obj.Active) + { + reader.show(); + reader.prop('src', frame_src_html5); + } + else + reader.hide(); + } }); }); - var base_url = '//reader.librelio.com'; - $('#reader-link').attr('href', base_url + '?' + - querystring.stringify({ - wapublisher: - s3AuthObj.rootDirectory, - waapp: app_name - })); + + $('#reader-link').attr('href', frame_src); var reader = $('