Initial commit: Backup der Webseiten
- zoesch.de - blitzkiste.net - gruene-hassberge (norbert.zoesch.de) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
404
zoesch.de/galerie/admin/themes/default/js/LocalStorageCache.js
Normal file
404
zoesch.de/galerie/admin/themes/default/js/LocalStorageCache.js
Normal file
@@ -0,0 +1,404 @@
|
||||
(function($, exports) {
|
||||
"use strict";
|
||||
|
||||
/**
|
||||
* Base LocalStorage cache
|
||||
*
|
||||
* @param options {object}
|
||||
* - key (required) identifier of the collection
|
||||
* - serverId (recommended) identifier of the Piwigo instance
|
||||
* - serverKey (required) state of collection server-side
|
||||
* - lifetime (optional) cache lifetime in seconds
|
||||
* - loader (required) function called to fetch data, takes a callback as first argument
|
||||
* which must be called with the loaded date
|
||||
*/
|
||||
var LocalStorageCache = function(options) {
|
||||
this._init(options);
|
||||
};
|
||||
|
||||
/*
|
||||
* Constructor (deported for easy inheritance)
|
||||
*/
|
||||
LocalStorageCache.prototype._init = function(options) {
|
||||
this.key = options.key + '_' + options.serverId;
|
||||
this.serverKey = options.serverKey;
|
||||
this.lifetime = options.lifetime ? options.lifetime*1000 : 3600*1000;
|
||||
this.loader = options.loader;
|
||||
|
||||
this.storage = window.localStorage;
|
||||
this.ready = !!this.storage;
|
||||
};
|
||||
|
||||
/*
|
||||
* Get the cache content
|
||||
* @param callback {function} called with the data as first parameter
|
||||
*/
|
||||
LocalStorageCache.prototype.get = function(callback) {
|
||||
var now = new Date().getTime(),
|
||||
that = this;
|
||||
|
||||
if (this.ready && this.storage[this.key] != undefined) {
|
||||
var cache = JSON.parse(this.storage[this.key]);
|
||||
|
||||
if (now - cache.timestamp <= this.lifetime && cache.key == this.serverKey) {
|
||||
callback(cache.data);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
this.loader(function(data) {
|
||||
that.set.call(that, data);
|
||||
callback(data);
|
||||
});
|
||||
};
|
||||
|
||||
/*
|
||||
* Manually set the cache content
|
||||
* @param data {mixed}
|
||||
*/
|
||||
LocalStorageCache.prototype.set = function(data) {
|
||||
if (this.ready) {
|
||||
this.storage[this.key] = JSON.stringify({
|
||||
timestamp: new Date().getTime(),
|
||||
key: this.serverKey,
|
||||
data: data
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
* Manually clear the cache
|
||||
*/
|
||||
LocalStorageCache.prototype.clear = function() {
|
||||
if (this.ready) {
|
||||
this.storage.removeItem(this.key);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Abstract class containing common initialization code for selectize
|
||||
*/
|
||||
var AbstractSelectizer = function(){};
|
||||
AbstractSelectizer.prototype = new LocalStorageCache({});
|
||||
|
||||
/*
|
||||
* Load Selectize with cache content
|
||||
* @param $target {jQuery} may have some data attributes (create, default, value)
|
||||
* @param options {object}
|
||||
* - value (optional) list of preselected items (ids, or objects with "id" attribute")
|
||||
* - default (optional) default value which will be forced if the select is emptyed
|
||||
* - create (optional) allow item user creation
|
||||
* - filter (optional) function called for each select before applying the data
|
||||
* takes two parameters: cache data, options
|
||||
* must return new data
|
||||
*/
|
||||
AbstractSelectizer.prototype._selectize = function($target, globalOptions) {
|
||||
$target.data('cache', this);
|
||||
|
||||
this.get(function(data) {
|
||||
$target.each(function() {
|
||||
var filtered, value, defaultValue,
|
||||
options = $.extend({}, globalOptions);
|
||||
|
||||
// apply filter function
|
||||
if (options.filter != undefined) {
|
||||
filtered = options.filter.call(this, data, options);
|
||||
}
|
||||
else {
|
||||
filtered = data;
|
||||
}
|
||||
|
||||
this.selectize.settings.maxOptions = filtered.length + 100;
|
||||
|
||||
// active creation mode
|
||||
if (this.hasAttribute('data-create')) {
|
||||
options.create = true;
|
||||
}
|
||||
this.selectize.settings.create = !!options.create;
|
||||
|
||||
// load options
|
||||
this.selectize.load(function(callback) {
|
||||
if ($.isEmptyObject(this.options)) {
|
||||
callback(filtered);
|
||||
}
|
||||
});
|
||||
|
||||
// load items
|
||||
if ((value = $(this).data('value'))) {
|
||||
options.value = value;
|
||||
}
|
||||
if (options.value != undefined) {
|
||||
$.each(value, $.proxy(function(i, cat) {
|
||||
if ($.isNumeric(cat))
|
||||
this.selectize.addItem(cat);
|
||||
else
|
||||
this.selectize.addItem(cat.id);
|
||||
}, this));
|
||||
}
|
||||
|
||||
// set default
|
||||
if ((defaultValue = $(this).data('default'))) {
|
||||
options.default = defaultValue;
|
||||
}
|
||||
if (options.default == 'first') {
|
||||
options.default = filtered[0] ? filtered[0].id : undefined;
|
||||
}
|
||||
|
||||
if (options.default != undefined) {
|
||||
// add default item
|
||||
if (this.selectize.getValue() == '') {
|
||||
this.selectize.addItem(options.default);
|
||||
}
|
||||
|
||||
// if multiple: prevent item deletion
|
||||
if (this.multiple) {
|
||||
this.selectize.getItem(options.default).find('.remove').hide();
|
||||
|
||||
this.selectize.on('item_remove', function(id) {
|
||||
if (id == options.default) {
|
||||
this.addItem(id);
|
||||
this.getItem(id).find('.remove').hide();
|
||||
}
|
||||
});
|
||||
}
|
||||
// if single: restore default on blur
|
||||
else {
|
||||
this.selectize.on('dropdown_close', function() {
|
||||
if (this.getValue() == '') {
|
||||
this.addItem(options.default);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
// redefine Selectize templates without escape
|
||||
AbstractSelectizer.getRender = function(field_label, lang) {
|
||||
lang = lang || { 'Add': 'Add' };
|
||||
|
||||
return {
|
||||
'option': function(data, escape) {
|
||||
return '<div class="option">' + data[field_label] + '</div>';
|
||||
},
|
||||
'item': function(data, escape) {
|
||||
return '<div class="item">' + data[field_label] + '</div>';
|
||||
},
|
||||
'option_create': function(data, escape) {
|
||||
return '<div class="create">' + lang['Add'] + ' <strong>' + data.input + '</strong>…</div>';
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Special LocalStorage for admin categories list
|
||||
*
|
||||
* @param options {object}
|
||||
* - serverId (recommended) identifier of the Piwigo instance
|
||||
* - serverKey (required) state of collection server-side
|
||||
* - rootUrl (required) used for WS call
|
||||
*/
|
||||
var CategoriesCache = function(options) {
|
||||
options.key = 'categoriesAdminList';
|
||||
|
||||
options.loader = function(callback) {
|
||||
$.getJSON(options.rootUrl + 'ws.php?format=json&method=pwg.categories.getAdminList', function(data) {
|
||||
var cats = data.result.categories.map(function(c, i) {
|
||||
c.pos = i;
|
||||
delete c['comment'];
|
||||
delete c['uppercats'];
|
||||
return c;
|
||||
});
|
||||
|
||||
callback(cats);
|
||||
});
|
||||
};
|
||||
|
||||
this._init(options);
|
||||
};
|
||||
|
||||
CategoriesCache.prototype = new AbstractSelectizer();
|
||||
|
||||
/*
|
||||
* Init Selectize with cache content
|
||||
* @see AbstractSelectizer._selectize
|
||||
*/
|
||||
CategoriesCache.prototype.selectize = function($target, options) {
|
||||
options = options || {};
|
||||
|
||||
$target.selectize({
|
||||
valueField: 'id',
|
||||
labelField: 'fullname',
|
||||
sortField: 'pos',
|
||||
searchField: ['fullname'],
|
||||
plugins: ['remove_button'],
|
||||
render: AbstractSelectizer.getRender('fullname', options.lang)
|
||||
});
|
||||
|
||||
this._selectize($target, options);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Special LocalStorage for admin tags list
|
||||
*
|
||||
* @param options {object}
|
||||
* - serverId (recommended) identifier of the Piwigo instance
|
||||
* - serverKey (required) state of collection server-side
|
||||
* - rootUrl (required) used for WS call
|
||||
*/
|
||||
var TagsCache = function(options) {
|
||||
options.key = 'tagsAdminList';
|
||||
|
||||
options.loader = function(callback) {
|
||||
$.getJSON(options.rootUrl + 'ws.php?format=json&method=pwg.tags.getAdminList', function(data) {
|
||||
var tags = data.result.tags.map(function(t) {
|
||||
t.id = '~~' + t.id + '~~';
|
||||
delete t['url_name'];
|
||||
delete t['lastmodified'];
|
||||
return t;
|
||||
});
|
||||
|
||||
callback(tags);
|
||||
});
|
||||
};
|
||||
|
||||
this._init(options);
|
||||
};
|
||||
|
||||
TagsCache.prototype = new AbstractSelectizer();
|
||||
|
||||
/*
|
||||
* Init Selectize with cache content
|
||||
* @see AbstractSelectizer._selectize
|
||||
*/
|
||||
TagsCache.prototype.selectize = function($target, options) {
|
||||
options = options || {};
|
||||
|
||||
$target.selectize({
|
||||
valueField: 'id',
|
||||
labelField: 'name',
|
||||
sortField: 'name',
|
||||
searchField: ['name'],
|
||||
plugins: ['remove_button'],
|
||||
render: AbstractSelectizer.getRender('name', options.lang)
|
||||
});
|
||||
|
||||
this._selectize($target, options);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Special LocalStorage for admin groups list
|
||||
*
|
||||
* @param options {object}
|
||||
* - serverId (recommended) identifier of the Piwigo instance
|
||||
* - serverKey (required) state of collection server-side
|
||||
* - rootUrl (required) used for WS call
|
||||
*/
|
||||
var GroupsCache = function(options) {
|
||||
options.key = 'groupsAdminList';
|
||||
|
||||
options.loader = function(callback) {
|
||||
$.getJSON(options.rootUrl + 'ws.php?format=json&method=pwg.groups.getList&per_page=9999', function(data) {
|
||||
var groups = data.result.groups.map(function(g) {
|
||||
delete g['lastmodified'];
|
||||
return g;
|
||||
});
|
||||
|
||||
callback(groups);
|
||||
});
|
||||
};
|
||||
|
||||
this._init(options);
|
||||
};
|
||||
|
||||
GroupsCache.prototype = new AbstractSelectizer();
|
||||
|
||||
/*
|
||||
* Init Selectize with cache content
|
||||
* @see AbstractSelectizer._selectize
|
||||
*/
|
||||
GroupsCache.prototype.selectize = function($target, options) {
|
||||
options = options || {};
|
||||
|
||||
$target.selectize({
|
||||
valueField: 'id',
|
||||
labelField: 'name',
|
||||
sortField: 'name',
|
||||
searchField: ['name'],
|
||||
plugins: ['remove_button'],
|
||||
render: AbstractSelectizer.getRender('name', options.lang)
|
||||
});
|
||||
|
||||
this._selectize($target, options);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Special LocalStorage for admin users list
|
||||
*
|
||||
* @param options {object}
|
||||
* - serverId (recommended) identifier of the Piwigo instance
|
||||
* - serverKey (required) state of collection server-side
|
||||
* - rootUrl (required) used for WS call
|
||||
*/
|
||||
var UsersCache = function(options) {
|
||||
options.key = 'usersAdminList';
|
||||
|
||||
options.loader = function(callback) {
|
||||
var users = [];
|
||||
|
||||
// recursive loader
|
||||
(function load(page){
|
||||
jQuery.getJSON(options.rootUrl + 'ws.php?format=json&method=pwg.users.getList&display=username&per_page=9999&page='+ page, function(data) {
|
||||
users = users.concat(data.result.users);
|
||||
|
||||
if (data.result.paging.count == data.result.paging.per_page) {
|
||||
load(++page);
|
||||
}
|
||||
else {
|
||||
callback(users);
|
||||
}
|
||||
});
|
||||
}(0));
|
||||
};
|
||||
|
||||
this._init(options);
|
||||
};
|
||||
|
||||
UsersCache.prototype = new AbstractSelectizer();
|
||||
|
||||
/*
|
||||
* Init Selectize with cache content
|
||||
* @see AbstractSelectizer._selectize
|
||||
*/
|
||||
UsersCache.prototype.selectize = function($target, options) {
|
||||
options = options || {};
|
||||
|
||||
$target.selectize({
|
||||
valueField: 'id',
|
||||
labelField: 'username',
|
||||
sortField: 'username',
|
||||
searchField: ['username'],
|
||||
plugins: ['remove_button'],
|
||||
render: AbstractSelectizer.getRender('username', options.lang)
|
||||
});
|
||||
|
||||
this._selectize($target, options);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Expose classes in global scope
|
||||
*/
|
||||
exports.LocalStorageCache = LocalStorageCache;
|
||||
exports.CategoriesCache = CategoriesCache;
|
||||
exports.TagsCache = TagsCache;
|
||||
exports.GroupsCache = GroupsCache;
|
||||
exports.UsersCache = UsersCache;
|
||||
|
||||
}(jQuery, window));
|
||||
117
zoesch.de/galerie/admin/themes/default/js/addAlbum.js
Normal file
117
zoesch.de/galerie/admin/themes/default/js/addAlbum.js
Normal file
@@ -0,0 +1,117 @@
|
||||
jQuery.fn.pwgAddAlbum = function(options) {
|
||||
options = options || {};
|
||||
|
||||
var $popup = jQuery('#addAlbumForm'),
|
||||
$albumParent = $popup.find('[name="category_parent"]')
|
||||
$button = jQuery(this),
|
||||
$target = jQuery('[name="'+ $button.data('addAlbum') +'"]'),
|
||||
cache = $target.data('cache');
|
||||
|
||||
if (!$target[0].selectize) {
|
||||
jQuery.error('pwgAddAlbum: target must use selectize');
|
||||
}
|
||||
if (!cache) {
|
||||
jQuery.error('pwgAddAlbum: missing categories cache');
|
||||
}
|
||||
|
||||
function init() {
|
||||
$popup.data('init', true);
|
||||
|
||||
cache.selectize($albumParent, {
|
||||
'default': 0,
|
||||
'filter': function(categories) {
|
||||
categories.push({
|
||||
id: 0,
|
||||
fullname: '------------',
|
||||
global_rank: 0
|
||||
});
|
||||
|
||||
if (options.filter) {
|
||||
categories = options.filter.call(this, categories);
|
||||
}
|
||||
|
||||
return categories;
|
||||
}
|
||||
});
|
||||
|
||||
$popup.find('form').on('submit', function(e) {
|
||||
e.preventDefault();
|
||||
|
||||
var parent_id = $albumParent.val(),
|
||||
name = $popup.find('[name=category_name]').val();
|
||||
|
||||
jQuery('#categoryNameError').toggle(!name);
|
||||
if (!name) {
|
||||
return;
|
||||
}
|
||||
|
||||
jQuery.ajax({
|
||||
url: 'ws.php?format=json',
|
||||
type: 'POST',
|
||||
dataType: 'json',
|
||||
data: {
|
||||
method: 'pwg.categories.add',
|
||||
parent: parent_id,
|
||||
name: name
|
||||
},
|
||||
beforeSend: function() {
|
||||
jQuery('#albumCreationLoading').show();
|
||||
},
|
||||
success: function(data) {
|
||||
jQuery('#albumCreationLoading').hide();
|
||||
$button.colorbox.close();
|
||||
|
||||
var newAlbum = {
|
||||
id: data.result.id,
|
||||
name: name,
|
||||
fullname: name,
|
||||
global_rank: '0',
|
||||
dir: null,
|
||||
nb_images: 0,
|
||||
pos: 0
|
||||
};
|
||||
|
||||
var parentSelectize = $albumParent[0].selectize;
|
||||
|
||||
if (parent_id != 0) {
|
||||
var parent = parentSelectize.options[parent_id];
|
||||
newAlbum.fullname = parent.fullname + ' / ' + newAlbum.fullname;
|
||||
newAlbum.global_rank = parent.global_rank + '.1';
|
||||
newAlbum.pos = parent.pos + 1;
|
||||
}
|
||||
|
||||
var targetSelectize = $target[0].selectize;
|
||||
targetSelectize.addOption(newAlbum);
|
||||
targetSelectize.setValue(newAlbum.id);
|
||||
|
||||
parentSelectize.addOption(newAlbum);
|
||||
|
||||
if (options.afterSelect) {
|
||||
options.afterSelect();
|
||||
}
|
||||
},
|
||||
error: function(XMLHttpRequest, textStatus, errorThrows) {
|
||||
jQuery('#albumCreationLoading').hide();
|
||||
alert(errorThrows);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
this.colorbox({
|
||||
inline: true,
|
||||
href: '#addAlbumForm',
|
||||
width: 650, height: 300,
|
||||
onComplete: function() {
|
||||
if (!$popup.data('init')) {
|
||||
init();
|
||||
}
|
||||
|
||||
jQuery('#categoryNameError').hide();
|
||||
$popup.find('[name=category_name]').val('').focus();
|
||||
$albumParent[0].selectize.setValue($target.val() || 0);
|
||||
}
|
||||
});
|
||||
|
||||
return this;
|
||||
};
|
||||
383
zoesch.de/galerie/admin/themes/default/js/batchManagerGlobal.js
Normal file
383
zoesch.de/galerie/admin/themes/default/js/batchManagerGlobal.js
Normal file
@@ -0,0 +1,383 @@
|
||||
|
||||
/* ********** Filters*/
|
||||
function filter_enable(filter) {
|
||||
/* show the filter*/
|
||||
$("#"+filter).show();
|
||||
|
||||
/* check the checkbox to declare we use this filter */
|
||||
$("input[type=checkbox][name="+filter+"_use]").prop("checked", true);
|
||||
|
||||
/* forbid to select this filter in the addFilter list */
|
||||
$("#addFilter").children("option[value="+filter+"]").attr("disabled", "disabled");
|
||||
}
|
||||
|
||||
function filter_disable(filter) {
|
||||
/* hide the filter line */
|
||||
$("#"+filter).hide();
|
||||
|
||||
/* uncheck the checkbox to declare we do not use this filter */
|
||||
$("input[name="+filter+"_use]").prop("checked", false);
|
||||
|
||||
/* give the possibility to show it again */
|
||||
$("#addFilter").children("option[value="+filter+"]").removeAttr("disabled");
|
||||
}
|
||||
|
||||
$(".removeFilter").addClass("icon-cancel-circled");
|
||||
|
||||
$(".removeFilter").click(function () {
|
||||
var filter = $(this).parent('li').attr("id");
|
||||
filter_disable(filter);
|
||||
|
||||
return false;
|
||||
});
|
||||
|
||||
$("#addFilter").change(function () {
|
||||
var filter = $(this).prop("value");
|
||||
filter_enable(filter);
|
||||
$(this).prop("value", -1);
|
||||
});
|
||||
|
||||
$("#removeFilters").click(function() {
|
||||
$("#filterList li").each(function() {
|
||||
var filter = $(this).attr("id");
|
||||
filter_disable(filter);
|
||||
});
|
||||
return false;
|
||||
});
|
||||
|
||||
$('[data-slider=widths]').pwgDoubleSlider(sliders.widths);
|
||||
$('[data-slider=heights]').pwgDoubleSlider(sliders.heights);
|
||||
$('[data-slider=ratios]').pwgDoubleSlider(sliders.ratios);
|
||||
$('[data-slider=filesizes]').pwgDoubleSlider(sliders.filesizes);
|
||||
|
||||
|
||||
/* ********** Thumbs */
|
||||
|
||||
/* Shift-click: select all photos between the click and the shift+click */
|
||||
jQuery(document).ready(function() {
|
||||
var last_clicked=0,
|
||||
last_clickedstatus=true;
|
||||
jQuery.fn.enableShiftClick = function() {
|
||||
var inputs = [],
|
||||
count=0;
|
||||
this.find('input[type=checkbox]').each(function() {
|
||||
var pos=count;
|
||||
inputs[count++]=this;
|
||||
$(this).bind("shclick", function (dummy,event) {
|
||||
if (event.shiftKey) {
|
||||
var first = last_clicked;
|
||||
var last = pos;
|
||||
if (first > last) {
|
||||
first=pos;
|
||||
last=last_clicked;
|
||||
}
|
||||
|
||||
for (var i=first; i<=last;i++) {
|
||||
input = $(inputs[i]);
|
||||
$(input).prop('checked', last_clickedstatus).trigger("change");
|
||||
if (last_clickedstatus)
|
||||
{
|
||||
$(input).closest("li").addClass("thumbSelected");
|
||||
}
|
||||
else
|
||||
{
|
||||
$(input).closest("li").removeClass("thumbSelected");
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
last_clicked = pos;
|
||||
last_clickedstatus = this.checked;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
$(this).click(function(event) { $(this).triggerHandler("shclick",event)});
|
||||
});
|
||||
}
|
||||
$('ul.thumbnails').enableShiftClick();
|
||||
});
|
||||
|
||||
jQuery("a.preview-box").colorbox( {photo: true} );
|
||||
|
||||
jQuery('.thumbnails img').tipTip({
|
||||
'delay' : 0,
|
||||
'fadeIn' : 200,
|
||||
'fadeOut' : 200
|
||||
});
|
||||
|
||||
|
||||
/* ********** Actions*/
|
||||
|
||||
jQuery('[data-datepicker]').pwgDatepicker({
|
||||
showTimepicker: true,
|
||||
cancelButton: lang.Cancel
|
||||
});
|
||||
|
||||
jQuery('[data-add-album]').pwgAddAlbum();
|
||||
|
||||
$("input[name=remove_author]").click(function () {
|
||||
if ($(this).is(':checked')) {
|
||||
$("input[name=author]").hide();
|
||||
}
|
||||
else {
|
||||
$("input[name=author]").show();
|
||||
}
|
||||
});
|
||||
|
||||
$("input[name=remove_title]").click(function () {
|
||||
if ($(this).is(':checked')) {
|
||||
$("input[name=title]").hide();
|
||||
}
|
||||
else {
|
||||
$("input[name=title]").show();
|
||||
}
|
||||
});
|
||||
|
||||
$("input[name=remove_date_creation]").click(function () {
|
||||
if ($(this).is(':checked')) {
|
||||
$("#set_date_creation").hide();
|
||||
}
|
||||
else {
|
||||
$("#set_date_creation").show();
|
||||
}
|
||||
});
|
||||
|
||||
var derivatives = {
|
||||
elements: null,
|
||||
done: 0,
|
||||
total: 0,
|
||||
|
||||
finished: function() {
|
||||
return derivatives.done == derivatives.total && derivatives.elements && derivatives.elements.length==0;
|
||||
}
|
||||
};
|
||||
|
||||
function progress(success) {
|
||||
jQuery('#progressBar').progressBar(derivatives.done, {
|
||||
max: derivatives.total,
|
||||
textFormat: 'fraction',
|
||||
boxImage: 'themes/default/images/progressbar.gif',
|
||||
barImage: 'themes/default/images/progressbg_orange.gif'
|
||||
});
|
||||
if (success !== undefined) {
|
||||
var type = success ? 'regenerateSuccess': 'regenerateError',
|
||||
s = jQuery('[name="'+type+'"]').val();
|
||||
jQuery('[name="'+type+'"]').val(++s);
|
||||
}
|
||||
|
||||
if (derivatives.finished()) {
|
||||
jQuery('#applyAction').click();
|
||||
}
|
||||
}
|
||||
|
||||
function getDerivativeUrls() {
|
||||
var ids = derivatives.elements.splice(0, 500);
|
||||
var params = {max_urls: 100000, ids: ids, types: []};
|
||||
jQuery("#action_generate_derivatives input").each( function(i, t) {
|
||||
if ($(t).is(":checked"))
|
||||
params.types.push( t.value );
|
||||
} );
|
||||
|
||||
jQuery.ajax( {
|
||||
type: "POST",
|
||||
url: 'ws.php?format=json&method=pwg.getMissingDerivatives',
|
||||
data: params,
|
||||
dataType: "json",
|
||||
success: function(data) {
|
||||
if (!data.stat || data.stat != "ok") {
|
||||
return;
|
||||
}
|
||||
derivatives.total += data.result.urls.length;
|
||||
progress();
|
||||
for (var i=0; i < data.result.urls.length; i++) {
|
||||
jQuery.manageAjax.add("queued", {
|
||||
type: 'GET',
|
||||
url: data.result.urls[i] + "&ajaxload=true",
|
||||
dataType: 'json',
|
||||
success: ( function(data) { derivatives.done++; progress(true) }),
|
||||
error: ( function(data) { derivatives.done++; progress(false) })
|
||||
});
|
||||
}
|
||||
if (derivatives.elements.length)
|
||||
setTimeout( getDerivativeUrls, 25 * (derivatives.total-derivatives.done));
|
||||
}
|
||||
} );
|
||||
}
|
||||
|
||||
function selectGenerateDerivAll() {
|
||||
$("#action_generate_derivatives input[type=checkbox]").prop("checked", true);
|
||||
}
|
||||
function selectGenerateDerivNone() {
|
||||
$("#action_generate_derivatives input[type=checkbox]").prop("checked", false);
|
||||
}
|
||||
|
||||
function selectDelDerivAll() {
|
||||
$("#action_delete_derivatives input[type=checkbox]").prop("checked", true);
|
||||
}
|
||||
function selectDelDerivNone() {
|
||||
$("#action_delete_derivatives input[type=checkbox]").prop("checked", false);
|
||||
}
|
||||
|
||||
/* delete photos by blocks, with progress bar */
|
||||
jQuery('#applyAction').click(function(e) {
|
||||
if (typeof(elements) != "undefined") {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (jQuery('[name="selectAction"]').val() == 'delete') {
|
||||
if (!jQuery("#action_delete input[name=confirm_deletion]").is(':checked')) {
|
||||
jQuery("#action_delete span.errors").show();
|
||||
return false;
|
||||
}
|
||||
e.stopPropagation();
|
||||
}
|
||||
else {
|
||||
return true;
|
||||
}
|
||||
|
||||
jQuery('.bulkAction').hide();
|
||||
jQuery('#regenerationText').html(lang.deleteProgressMessage);
|
||||
var maxRequests=1;
|
||||
|
||||
var queuedManager = jQuery.manageAjax.create('queued', {
|
||||
queue: true,
|
||||
cacheResponse: false,
|
||||
maxRequests: maxRequests
|
||||
});
|
||||
|
||||
elements = Array();
|
||||
|
||||
if (jQuery('input[name=setSelected]').is(':checked')) {
|
||||
elements = all_elements;
|
||||
}
|
||||
else {
|
||||
jQuery('input[name="selection[]"]').filter(':checked').each(function() {
|
||||
elements.push(jQuery(this).val());
|
||||
});
|
||||
}
|
||||
|
||||
progressBar_max = elements.length;
|
||||
var todo = 0;
|
||||
var deleteBlockSize = Math.min(
|
||||
Number((elements.length/2).toFixed()),
|
||||
1000
|
||||
);
|
||||
var image_ids = Array();
|
||||
|
||||
jQuery('#applyActionBlock').hide();
|
||||
jQuery('select[name="selectAction"]').hide();
|
||||
jQuery('#regenerationMsg').show();
|
||||
jQuery('#progressBar').progressBar(0, {
|
||||
max: progressBar_max,
|
||||
textFormat: 'fraction',
|
||||
boxImage: 'themes/default/images/progressbar.gif',
|
||||
barImage: 'themes/default/images/progressbg_orange.gif'
|
||||
});
|
||||
|
||||
for (i=0;i<elements.length;i++) {
|
||||
image_ids.push(elements[i]);
|
||||
if (i % deleteBlockSize != deleteBlockSize - 1 && i != elements.length - 1) {
|
||||
continue;
|
||||
}
|
||||
|
||||
(function(ids) {
|
||||
var thisBatchSize = ids.length;
|
||||
queuedManager.add({
|
||||
type: 'POST',
|
||||
url: 'ws.php?format=json',
|
||||
data: {
|
||||
method: "pwg.images.delete",
|
||||
pwg_token: jQuery("input[name=pwg_token]").val(),
|
||||
image_id: ids.join(',')
|
||||
},
|
||||
dataType: 'json',
|
||||
success: function(data) {
|
||||
todo += thisBatchSize;
|
||||
var isOk = data.stat && "ok" == data.stat;
|
||||
if (isOk && data.result != thisBatchSize)
|
||||
/*TODO: user feedback only data.result images out of thisBatchSize were deleted*/;
|
||||
/*TODO: user feedback if isError*/
|
||||
progressDelete(todo, progressBar_max, isOk);
|
||||
},
|
||||
error: function(data) {
|
||||
todo += thisBatchSize;
|
||||
/*TODO: user feedback*/
|
||||
progressDelete(todo, progressBar_max, false);
|
||||
}
|
||||
});
|
||||
} )(image_ids);
|
||||
|
||||
image_ids = Array();
|
||||
}
|
||||
return false;
|
||||
});
|
||||
|
||||
function progressDelete(val, max, success) {
|
||||
jQuery('#progressBar').progressBar(val, {
|
||||
max: max,
|
||||
textFormat: 'fraction',
|
||||
boxImage: 'themes/default/images/progressbar.gif',
|
||||
barImage: 'themes/default/images/progressbg_orange.gif'
|
||||
});
|
||||
|
||||
if (val == max) {
|
||||
jQuery('#applyAction').click();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
jQuery("#action_delete input[name=confirm_deletion]").change(function() {
|
||||
jQuery("#action_delete span.errors").hide();
|
||||
});
|
||||
|
||||
|
||||
jQuery('#delete_orphans').click(function(e) {
|
||||
jQuery(this).hide();
|
||||
jQuery('#orphans_deletion').show();
|
||||
|
||||
var deleteBlockSize = Math.min(
|
||||
Number((jQuery('#orphans_to_delete').data('origin') / 2).toFixed()),
|
||||
1000
|
||||
);
|
||||
|
||||
delete_orphans_block(deleteBlockSize);
|
||||
|
||||
return false;
|
||||
});
|
||||
|
||||
function delete_orphans_block(blockSize) {
|
||||
jQuery.ajax({
|
||||
url: "ws.php?format=json&method=pwg.images.deleteOrphans",
|
||||
type:"POST",
|
||||
dataType: "json",
|
||||
data: {
|
||||
pwg_token: jQuery("input[name=pwg_token").val(),
|
||||
block_size: blockSize
|
||||
},
|
||||
success:function(data) {
|
||||
jQuery('#orphans_to_delete').html(data.result.nb_orphans);
|
||||
|
||||
var percent_remaining = Number(
|
||||
(data.result.nb_orphans * 100 / jQuery('#orphans_to_delete').data('origin')).toFixed()
|
||||
);
|
||||
var percent_done = 100 - percent_remaining;
|
||||
jQuery('#orphans_deleted').html(percent_done);
|
||||
|
||||
if (data.result.nb_orphans > 0) {
|
||||
delete_orphans_block();
|
||||
}
|
||||
else {
|
||||
// time to refresh the whole page
|
||||
var redirect_to = 'admin.php?page=batch_manager';
|
||||
redirect_to += '&action=delete_orphans';
|
||||
redirect_to += '&nb_orphans_deleted='+jQuery('#orphans_to_delete').data('origin');
|
||||
|
||||
document.location = redirect_to;
|
||||
}
|
||||
},
|
||||
error:function(XMLHttpRequest) {
|
||||
jQuery('#orphans_deletion').hide();
|
||||
jQuery('#orphans_deletion_error').show().html('error '+XMLHttpRequest.status+' : '+XMLHttpRequest.statusText);
|
||||
}
|
||||
});
|
||||
}
|
||||
123
zoesch.de/galerie/admin/themes/default/js/common.js
Normal file
123
zoesch.de/galerie/admin/themes/default/js/common.js
Normal file
@@ -0,0 +1,123 @@
|
||||
jQuery.fn.fontCheckbox = function() {
|
||||
/* checkbox */
|
||||
this.find('input[type=checkbox]').each(function() {
|
||||
if (!jQuery(this).is(':checked')) {
|
||||
jQuery(this).prev().toggleClass('icon-check icon-check-empty');
|
||||
}
|
||||
});
|
||||
this.find('input[type=checkbox]').on('change', function() {
|
||||
jQuery(this).prev().removeClass();
|
||||
if (!jQuery(this).is(':checked')) {
|
||||
jQuery(this).prev().addClass('icon-check-empty');
|
||||
}
|
||||
else {
|
||||
jQuery(this).prev().addClass('icon-check');
|
||||
}
|
||||
});
|
||||
|
||||
/* radio */
|
||||
this.find('input[type=radio]').each(function() {
|
||||
if (!jQuery(this).is(':checked')) {
|
||||
jQuery(this).prev().toggleClass('icon-dot-circled icon-circle-empty');
|
||||
}
|
||||
});
|
||||
this.find('input[type=radio]').on('change', function() {
|
||||
jQuery('.font-checkbox input[type=radio][name="'+ jQuery(this).attr('name') +'"]').each(function() {
|
||||
jQuery(this).prev().removeClass();
|
||||
if (!jQuery(this).is(':checked')) {
|
||||
jQuery(this).prev().addClass('icon-circle-empty');
|
||||
}
|
||||
else {
|
||||
jQuery(this).prev().addClass('icon-dot-circled');
|
||||
}
|
||||
})
|
||||
});
|
||||
};
|
||||
|
||||
// init fontChecbox everywhere
|
||||
jQuery('.font-checkbox').fontCheckbox();
|
||||
|
||||
function array_delete(arr, item) {
|
||||
var i = arr.indexOf(item);
|
||||
if (i != -1) arr.splice(i, 1);
|
||||
}
|
||||
|
||||
function str_repeat(i, m) {
|
||||
for (var o = []; m > 0; o[--m] = i);
|
||||
return o.join('');
|
||||
}
|
||||
|
||||
if (!Array.prototype.indexOf)
|
||||
{
|
||||
Array.prototype.indexOf = function(elt /*, from*/)
|
||||
{
|
||||
var len = this.length;
|
||||
|
||||
var from = Number(arguments[1]) || 0;
|
||||
from = (from < 0)
|
||||
? Math.ceil(from)
|
||||
: Math.floor(from);
|
||||
if (from < 0)
|
||||
from += len;
|
||||
|
||||
for (; from < len; from++)
|
||||
{
|
||||
if (from in this &&
|
||||
this[from] === elt)
|
||||
return from;
|
||||
}
|
||||
return -1;
|
||||
};
|
||||
}
|
||||
|
||||
function getRandomInt(min, max) {
|
||||
min = Math.ceil(min);
|
||||
max = Math.floor(max);
|
||||
return Math.floor(Math.random() * (max - min)) + min;
|
||||
}
|
||||
|
||||
function sprintf() {
|
||||
var i = 0, a, f = arguments[i++], o = [], m, p, c, x, s = '';
|
||||
while (f) {
|
||||
if (m = /^[^\x25]+/.exec(f)) {
|
||||
o.push(m[0]);
|
||||
}
|
||||
else if (m = /^\x25{2}/.exec(f)) {
|
||||
o.push('%');
|
||||
}
|
||||
else if (m = /^\x25(?:(\d+)\$)?(\+)?(0|'[^$])?(-)?(\d+)?(?:\.(\d+))?([b-fosuxX])/.exec(f)) {
|
||||
if (((a = arguments[m[1] || i++]) == null) || (a == undefined)) {
|
||||
throw('Too few arguments.');
|
||||
}
|
||||
if (/[^s]/.test(m[7]) && (typeof(a) != 'number')) {
|
||||
throw('Expecting number but found ' + typeof(a));
|
||||
}
|
||||
|
||||
switch (m[7]) {
|
||||
case 'b': a = a.toString(2); break;
|
||||
case 'c': a = String.fromCharCode(a); break;
|
||||
case 'd': a = parseInt(a); break;
|
||||
case 'e': a = m[6] ? a.toExponential(m[6]) : a.toExponential(); break;
|
||||
case 'f': a = m[6] ? parseFloat(a).toFixed(m[6]) : parseFloat(a); break;
|
||||
case 'o': a = a.toString(8); break;
|
||||
case 's': a = ((a = String(a)) && m[6] ? a.substring(0, m[6]) : a); break;
|
||||
case 'u': a = Math.abs(a); break;
|
||||
case 'x': a = a.toString(16); break;
|
||||
case 'X': a = a.toString(16).toUpperCase(); break;
|
||||
}
|
||||
|
||||
a = (/[def]/.test(m[7]) && m[2] && a >= 0 ? '+'+ a : a);
|
||||
c = m[3] ? m[3] == '0' ? '0' : m[3].charAt(1) : ' ';
|
||||
x = m[5] - String(a).length - s.length;
|
||||
p = m[5] ? str_repeat(c, x) : '';
|
||||
o.push(s + (m[4] ? a + p : p + a));
|
||||
}
|
||||
else {
|
||||
throw('Huh ?!');
|
||||
}
|
||||
|
||||
f = f.substring(m[0].length);
|
||||
}
|
||||
|
||||
return o.join('');
|
||||
}
|
||||
184
zoesch.de/galerie/admin/themes/default/js/datepicker.js
Normal file
184
zoesch.de/galerie/admin/themes/default/js/datepicker.js
Normal file
@@ -0,0 +1,184 @@
|
||||
(function($) {
|
||||
jQuery.timepicker.log = jQuery.noop; // that's ugly, but the timepicker is acting weird and throws parsing errors
|
||||
|
||||
|
||||
// modify DatePicker internal methods to replace year select by a numeric input
|
||||
var origGenerateMonthYearHeader = $.datepicker._generateMonthYearHeader,
|
||||
origSelectMonthYear = $.datepicker._selectMonthYear;
|
||||
|
||||
$.datepicker._generateMonthYearHeader = function(inst, drawMonth, drawYear, minDate, maxDate,
|
||||
secondary, monthNames, monthNamesShort) {
|
||||
|
||||
var html = origGenerateMonthYearHeader.call(this, inst, drawMonth, drawYear, minDate, maxDate,
|
||||
secondary, monthNames, monthNamesShort);
|
||||
|
||||
var yearshtml = "<input type='number' class='ui-datepicker-year' data-handler='selectYear' data-event='change keyup' value='"+drawYear+"' style='width:4em;margin-left:2px;'>";
|
||||
|
||||
return html.replace(new RegExp('<select class=\'ui-datepicker-year\'.*</select>', 'gm'), yearshtml);
|
||||
};
|
||||
|
||||
$.datepicker._selectMonthYear = debounce(function(id, select, period) {
|
||||
if (period === 'M') {
|
||||
origSelectMonthYear.call(this, id, select, period);
|
||||
}
|
||||
else {
|
||||
var target = $(id),
|
||||
inst = this._getInst(target[0]),
|
||||
val = parseInt(select.value, 10);
|
||||
|
||||
if (isNaN(val)) {
|
||||
inst['drawYear'] = '';
|
||||
}
|
||||
else {
|
||||
inst['selectedYear'] = inst['drawYear'] = val;
|
||||
|
||||
this._notifyChange(inst);
|
||||
this._adjustDate(target);
|
||||
|
||||
$('.ui-datepicker-year').focus();
|
||||
}
|
||||
}
|
||||
}, 500);
|
||||
|
||||
|
||||
// plugin definition
|
||||
jQuery.fn.pwgDatepicker = function(settings) {
|
||||
var options = jQuery.extend(true, {
|
||||
showTimepicker: false,
|
||||
cancelButton: false,
|
||||
}, settings || {});
|
||||
|
||||
return this.each(function() {
|
||||
var $this = jQuery(this),
|
||||
originalValue = $this.val(),
|
||||
originalDate,
|
||||
$target = jQuery('[name="'+ $this.data('datepicker') +'"]'),
|
||||
linked = !!$target.length,
|
||||
$start, $end;
|
||||
|
||||
if (linked) {
|
||||
originalValue = $target.val();
|
||||
}
|
||||
|
||||
// custom setter
|
||||
function set(date, init) {
|
||||
if (date === '') date = null;
|
||||
$this.datetimepicker('setDate', date);
|
||||
|
||||
if ($this.data('datepicker-start') && $start) {
|
||||
$start.datetimepicker('option', 'maxDate', date);
|
||||
}
|
||||
else if ($this.data('datepicker-end') && $end) {
|
||||
if (!init) { // on init, "end" is not initialized yet (assuming "start" is before "end" in the DOM)
|
||||
$end.datetimepicker('option', 'minDate', date);
|
||||
}
|
||||
}
|
||||
|
||||
if (!date && linked) {
|
||||
$target.val('');
|
||||
}
|
||||
}
|
||||
|
||||
// and custom cancel button
|
||||
if (options.cancelButton) {
|
||||
options.beforeShow = options.onChangeMonthYear = function() {
|
||||
setTimeout(function() {
|
||||
var buttonPane = $this.datepicker('widget')
|
||||
.find('.ui-datepicker-buttonpane');
|
||||
|
||||
if (buttonPane.find('.pwg-datepicker-cancel').length == 0) {
|
||||
$('<button type="button">'+ options.cancelButton +'</button>')
|
||||
.on('click', function() {
|
||||
set(originalDate, false);
|
||||
$this.datepicker('hide').blur();
|
||||
})
|
||||
.addClass('pwg-datepicker-cancel ui-state-error ui-corner-all')
|
||||
.appendTo(buttonPane);
|
||||
}
|
||||
}, 1);
|
||||
};
|
||||
}
|
||||
|
||||
// init picker
|
||||
$this.datetimepicker(jQuery.extend({
|
||||
dateFormat: linked ? 'DD d MM yy' : 'yy-mm-dd',
|
||||
timeFormat: 'HH:mm',
|
||||
separator: options.showTimepicker ? ' ' : '',
|
||||
|
||||
altField: linked ? $target : null,
|
||||
altFormat: 'yy-mm-dd',
|
||||
altTimeFormat: options.showTimepicker ? 'HH:mm:ss' : '',
|
||||
|
||||
autoSize: true,
|
||||
changeMonth : true,
|
||||
changeYear: true,
|
||||
altFieldTimeOnly: false,
|
||||
showSecond: false,
|
||||
alwaysSetTime: false
|
||||
}, options));
|
||||
|
||||
// attach range pickers
|
||||
if ($this.data('datepicker-start')) {
|
||||
$start = jQuery('[data-datepicker="'+ $this.data('datepicker-start') +'"]');
|
||||
|
||||
$this.datetimepicker('option', 'onClose', function(date) {
|
||||
$start.datetimepicker('option', 'maxDate', date);
|
||||
});
|
||||
|
||||
$this.datetimepicker('option', 'minDate', $start.datetimepicker('getDate'));
|
||||
}
|
||||
else if ($this.data('datepicker-end')) {
|
||||
$end = jQuery('[data-datepicker="'+ $this.data('datepicker-end') +'"]');
|
||||
|
||||
$this.datetimepicker('option', 'onClose', function(date) {
|
||||
$end.datetimepicker('option', 'minDate', date);
|
||||
});
|
||||
}
|
||||
|
||||
// attach unset button
|
||||
if ($this.data('datepicker-unset')) {
|
||||
jQuery('#'+ $this.data('datepicker-unset')).on('click', function(e) {
|
||||
e.preventDefault();
|
||||
set(null, false);
|
||||
});
|
||||
}
|
||||
|
||||
// set value from linked input
|
||||
if (linked) {
|
||||
var splitted = originalValue.split(' ');
|
||||
if (splitted.length == 2 && options.showTimepicker) {
|
||||
set(jQuery.datepicker.parseDateTime('yy-mm-dd', 'HH:mm:ss', originalValue), true);
|
||||
}
|
||||
else if (splitted[0].length == 10) {
|
||||
set(jQuery.datepicker.parseDate('yy-mm-dd', splitted[0]), true);
|
||||
}
|
||||
else {
|
||||
set(null, true);
|
||||
}
|
||||
}
|
||||
|
||||
originalDate = $this.datetimepicker('getDate');
|
||||
|
||||
// autoSize not handled by timepicker
|
||||
if (options.showTimepicker) {
|
||||
$this.attr('size', parseInt($this.attr('size'))+6);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
function debounce(func, wait, immediate) {
|
||||
var timeout;
|
||||
return function() {
|
||||
var context = this, args = arguments;
|
||||
var later = function() {
|
||||
timeout = null;
|
||||
if (!immediate) func.apply(context, args);
|
||||
};
|
||||
var callNow = immediate && !timeout;
|
||||
clearTimeout(timeout);
|
||||
timeout = setTimeout(later, wait);
|
||||
if (callNow) func.apply(context, args);
|
||||
};
|
||||
}
|
||||
|
||||
}(jQuery));
|
||||
62
zoesch.de/galerie/admin/themes/default/js/doubleSlider.js
Normal file
62
zoesch.de/galerie/admin/themes/default/js/doubleSlider.js
Normal file
@@ -0,0 +1,62 @@
|
||||
(function($){
|
||||
|
||||
/**
|
||||
* OPTIONS:
|
||||
* values {mixed[]}
|
||||
* selected {object} min and max
|
||||
* text {string}
|
||||
*/
|
||||
$.fn.pwgDoubleSlider = function(options) {
|
||||
var that = this;
|
||||
|
||||
function onChange(e, ui) {
|
||||
that.find('[data-input=min]').val(options.values[ui.values[0]]);
|
||||
that.find('[data-input=max]').val(options.values[ui.values[1]]);
|
||||
|
||||
that.find('.slider-info').html(sprintf(
|
||||
options.text,
|
||||
options.values[ui.values[0]],
|
||||
options.values[ui.values[1]]
|
||||
));
|
||||
}
|
||||
|
||||
function findClosest(array, value) {
|
||||
var closest = null, index = -1;
|
||||
$.each(array, function(i, v){
|
||||
if (closest == null || Math.abs(v - value) < Math.abs(closest - value)) {
|
||||
closest = v;
|
||||
index = i;
|
||||
}
|
||||
});
|
||||
return index;
|
||||
}
|
||||
|
||||
var values = [
|
||||
options.values.indexOf(options.selected.min),
|
||||
options.values.indexOf(options.selected.max)
|
||||
];
|
||||
if (values[0] == -1) {
|
||||
values[0] = findClosest(options.values, options.selected.min);
|
||||
}
|
||||
if (values[1] == -1) {
|
||||
values[1] = findClosest(options.values, options.selected.max);
|
||||
}
|
||||
|
||||
var slider = this.find('.slider-slider').slider({
|
||||
range: true,
|
||||
min: 0,
|
||||
max: options.values.length - 1,
|
||||
values: values,
|
||||
slide: onChange,
|
||||
change: onChange
|
||||
});
|
||||
|
||||
this.find('.slider-choice').on('click', function(){
|
||||
slider.slider('values', 0, options.values.indexOf($(this).data('min')));
|
||||
slider.slider('values', 1, options.values.indexOf($(this).data('max')));
|
||||
});
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
}(jQuery));
|
||||
62
zoesch.de/galerie/admin/themes/default/js/jquery.geoip.js
Normal file
62
zoesch.de/galerie/admin/themes/default/js/jquery.geoip.js
Normal file
@@ -0,0 +1,62 @@
|
||||
|
||||
GeoIp = {
|
||||
cache: {},
|
||||
pending: {},
|
||||
|
||||
get: function(ip, callback){
|
||||
if (!GeoIp.storageInit && window.localStorage) {
|
||||
GeoIp.storageInit = true;
|
||||
var cache = localStorage.getItem("freegeoip");
|
||||
if (cache) {
|
||||
cache = JSON.parse(cache);
|
||||
for (var key in cache) {
|
||||
var data = cache[key];
|
||||
if ( (new Date()).getTime() - data.reqTime > 96 * 3600000)
|
||||
delete cache[key];
|
||||
}
|
||||
GeoIp.cache = cache;
|
||||
}
|
||||
jQuery(window).on("unload", function() {
|
||||
localStorage.setItem("freegeoip", JSON.stringify(GeoIp.cache) );
|
||||
} );
|
||||
}
|
||||
|
||||
if (GeoIp.cache.hasOwnProperty(ip))
|
||||
callback(GeoIp.cache[ip]);
|
||||
else if (GeoIp.pending[ip])
|
||||
GeoIp.pending[ip].push(callback);
|
||||
else {
|
||||
GeoIp.pending[ip] = [callback];
|
||||
jQuery.ajax( {
|
||||
url: "http://freegeoip.net/json/" + ip,
|
||||
dataType: "jsonp",
|
||||
cache: true,
|
||||
timeout: 5000,
|
||||
success: function(data) {
|
||||
data.reqTime = (new Date()).getTime();
|
||||
var res=[];
|
||||
if (data.city) res.push(data.city);
|
||||
if (data.region_name) res.push(data.region_name);
|
||||
if (data.country_name) res.push(data.country_name);
|
||||
data.fullName = res.join(", ");
|
||||
|
||||
GeoIp.cache[ip] = data;
|
||||
var callbacks = GeoIp.pending[ip];
|
||||
delete GeoIp.pending[ip];
|
||||
for (var i=0; i<callbacks.length; i++)
|
||||
callbacks[i].call(null, data);
|
||||
},
|
||||
|
||||
error: function() {
|
||||
var data = {ip:ip, reqTime: (new Date()).getTime()};
|
||||
|
||||
GeoIp.cache[ip] = data;
|
||||
var callbacks = GeoIp.pending[ip];
|
||||
delete GeoIp.pending[ip];
|
||||
for (var i=0; i<callbacks.length; i++)
|
||||
callbacks[i].call(null, data);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user