Merge branch 'dev' of https://codeberg.org/zot/zap into dev

This commit is contained in:
Papa Dragon 2020-08-28 21:26:16 +02:00
commit 85af78c9d6
20 changed files with 278 additions and 225 deletions

View file

@ -166,19 +166,20 @@ class Cron {
if($r) {
require_once('include/photo_factory.php');
foreach($r as $rr) {
$photos = import_xchan_photo($rr['xchan_photo_l'],$rr['xchan_hash']);
$x = q("update xchan set xchan_photo_l = '%s', xchan_photo_m = '%s', xchan_photo_s = '%s', xchan_photo_mimetype = '%s'
where xchan_hash = '%s'",
dbesc($photos[0]),
dbesc($photos[1]),
dbesc($photos[2]),
dbesc($photos[3]),
dbesc($rr['xchan_hash'])
);
$photos = import_remote_xchan_photo($rr['xchan_photo_l'],$rr['xchan_hash']);
if ($photos) {
$x = q("update xchan set xchan_photo_l = '%s', xchan_photo_m = '%s', xchan_photo_s = '%s', xchan_photo_mimetype = '%s'
where xchan_hash = '%s'",
dbesc($photos[0]),
dbesc($photos[1]),
dbesc($photos[2]),
dbesc($photos[3]),
dbesc($rr['xchan_hash'])
);
}
}
}
// pull in some public posts
$disable_discover_tab = get_config('system','disable_discover_tab') || get_config('system','disable_discover_tab') === false;

View file

@ -81,6 +81,12 @@ class Cron_daily {
Run::Summon(array('Expire'));
Run::Summon(array('Cli_suggest'));
// remove xchan photos that were stored in the DB ine earlier versions
// and were migrated to filesystem storage.
// eventually this will do nothing but waste cpu cycles checking to see if anything remains.
cleanup_xchan_photos();
remove_obsolete_hublocs();
call_hooks('cron_daily',datetime_convert());

View file

@ -18,15 +18,17 @@ class Xchan_photo {
set_time_limit(90);
$photos = import_xchan_photo($url,$xchan);
$r = q("update xchan set xchan_photo_date = '%s', xchan_photo_l = '%s', xchan_photo_m = '%s', xchan_photo_s = '%s', xchan_photo_mimetype = '%s' where xchan_hash = '%s'",
dbescdate(datetime_convert()),
dbesc($photos[0]),
dbesc($photos[1]),
dbesc($photos[2]),
dbesc($photos[3]),
dbesc($xchan)
);
$photos = import_remote_xchan_photo($url,$xchan);
if ($photos) {
$r = q("update xchan set xchan_photo_date = '%s', xchan_photo_l = '%s', xchan_photo_m = '%s', xchan_photo_s = '%s', xchan_photo_mimetype = '%s' where xchan_hash = '%s'",
dbescdate(datetime_convert()),
dbesc($photos[0]),
dbesc($photos[1]),
dbesc($photos[2]),
dbesc($photos[3]),
dbesc($xchan)
);
}
return;
}

View file

@ -1059,8 +1059,8 @@ class Apps {
}
if ($arr['photo'] && (strpos($arr['photo'],'icon:') === false) && (strpos($arr['photo'],z_root()) === false)) {
$x = import_xchan_photo(str_replace('$baseurl',z_root(),$arr['photo']),get_observer_hash(),true);
if (! $x[4]) {
$x = import_remote_xchan_photo(str_replace('$baseurl',z_root(),$arr['photo']),get_observer_hash(),true);
if ((! $x) || ($x[4])) {
// $x[4] = true indicates storage failure of our cached/resized copy. If this failed, just keep the original url.
$arr['photo'] = $x[1];
}
@ -1150,8 +1150,8 @@ class Apps {
}
if ($arr['photo'] && (strpos($arr['photo'],'icon:') === false) && (strpos($arr['photo'],z_root()) === false)) {
$x = import_xchan_photo(str_replace('$baseurl',z_root(),$arr['photo']),get_observer_hash(),true);
if (! $x[4]) {
$x = import_remote_xchan_photo(str_replace('$baseurl',z_root(),$arr['photo']),get_observer_hash(),true);
if ((! $x) || ($x[4])) {
// $x[4] = true indicates storage failure of our cached/resized copy. If this failed, just keep the original url.
$arr['photo'] = $x[1];
}

View file

@ -47,14 +47,16 @@ class Img_cache {
$x = z_fetch_url($url,true,$redirects,[ 'filep' => $fp, 'novalidate' => true ]);
fclose($fp);
if ($x['success']) {
$i = getimagesize($file);
if ($x['success'] && file_exists($file)) {
$i = @getimagesize($file);
if ($i && $i[2]) { // looking for non-zero imagetype
Run::Summon( [ 'CacheThumb' , basename($file) ] );
return true;
}
}
unlink($file);
if (file_exists($file)) {
unlink($file);
}
return false;
}

View file

@ -915,7 +915,7 @@ class Libzot {
}
}
else {
$photos = import_xchan_photo($arr['photo']['url'], $xchan_hash);
$photos = import_remote_xchan_photo($arr['photo']['url'], $xchan_hash);
}
if ($photos) {
if ($photos[4]) {

View file

@ -53,10 +53,6 @@ class Acl extends Controller {
// and also contains xid without urlencode, used specifically by activity_filter widget
// $_REQUEST['query'] contains autocomplete search text.
// List of channels whose connections to also suggest,
// e.g. currently viewed channel or channels mentioned in a post
$extra_channels = (x($_REQUEST,'extra_channels') ? $_REQUEST['extra_channels'] : array());
// The different autocomplete libraries use different names for the search text
// parameter. Internally we'll use $search to represent the search text no matter
@ -151,59 +147,9 @@ class Acl extends Controller {
}
if ($type == '' || $type == 'c' || $type === 'f') {
$extra_channels_sql = '';
// Only include channels who allow the observer to view their connections
if ($extra_channels) {
foreach ($extra_channels as $channel) {
if (perm_is_allowed(intval($channel), get_observer_hash(),'view_contacts')) {
if ($extra_channels_sql) {
$extra_channels_sql .= ',';
}
$extra_channels_sql .= intval($channel);
}
}
}
// Getting info from the abook is better for local users because it contains info about permissions
if (local_channel()) {
if ($extra_channels_sql != '') {
$extra_channels_sql = " OR (abook_channel IN ($extra_channels_sql)) and abook_hidden = 0 ";
}
// Add atokens belonging to the local channel
if ($search) {
$sql_extra_atoken = "AND ( atoken_name LIKE " . protect_sprintf( "'%" . dbesc($search) . "%'" ) . ") ";
}
else {
$sql_extra_atoken = '';
}
$r2 = null;
$r1 = q("select * from atoken where atoken_uid = %d $sql_extra_atoken",
intval(local_channel())
);
if ($r1) {
require_once('include/security.php');
$r2 = array();
foreach ($r1 as $rr) {
$x = atoken_xchan($rr);
$r2[] = [
'id' => 'a' . $rr['atoken_id'] ,
'hash' => $x['xchan_hash'],
'name' => $x['xchan_name'],
'micro' => $x['xchan_photo_m'],
'url' => z_root(),
'nick' => $x['xchan_addr'],
'abook_flags' => 0,
'abook_self' => 0
];
}
}
// add connections
@ -224,50 +170,10 @@ class Acl extends Controller {
dbesc(get_observer_hash())
);
// Find contacts of extra channels
// This is probably more complicated than it needs to be
if ($extra_channels_sql) {
// Build a list of hashes that we got previously so we don't get them again
$known_hashes = array("'".get_observer_hash()."'");
if ($r) {
foreach ($r as $rr) {
$known_hashes[] = "'".$rr['hash']."'";
}
}
$known_hashes_sql = 'AND xchan_hash not in (' . implode(',',$known_hashes) . ')';
$r2 = q("SELECT abook_id as id, xchan_hash as hash, xchan_name as name, xchan_photo_s as micro, xchan_url as url, xchan_addr as nick, abook_flags, abook_self
FROM abook left join xchan on abook_xchan = xchan_hash
WHERE abook_channel IN ($extra_channels_sql) $known_hashes_sql AND abook_blocked = 0 and abook_pending = 0 and abook_hidden = 0 and xchan_deleted = 0 $sql_extra2 order by $order_extra2 xchan_name asc");
if ($r2) {
$r = array_merge($r,$r2);
}
// Sort accoring to match position, then alphabetically. This could be avoided if the above two SQL queries could be combined into one, and the sorting could be done on the SQl server (like in the case of a local user)
$matchpos = function($x) use($search) {
$namepos = strpos($x['name'],$search);
$nickpos = strpos($x['nick'],$search);
// Use a large position if not found
return min($namepos === false ? 9999 : $namepos, $nickpos === false ? 9999 : $nickpos);
};
// This could be made simpler if PHP supported stable sorting
usort($r,function($a,$b) use($matchpos) {
$pos1 = $matchpos($a);
$pos2 = $matchpos($b);
if ($pos1 == $pos2) { // Order alphabetically if match position is the same
if ($a['name'] == $b['name']) {
return 0;
}
else {
return ($a['name'] < $b['name']) ? -1 : 1;
}
}
return ($pos1 < $pos2) ? -1 : 1;
});
}
}
if ((count($r) < 100) && $type == 'c') {
$r2 = q("SELECT substr(xchan_hash,1,18) as id, xchan_hash as hash, xchan_name as name, xchan_photo_s as micro, xchan_url as url, xchan_addr as nick, 0 as abook_flags, 0 as abook_self
FROM xchan WHERE xchan_deleted = 0 and not xchan_network in ('rss','anon','unknown') $sql_extra2 order by $order_extra2 xchan_name asc"
$r2 = q("SELECT xchan_hash as id, xchan_hash as hash, xchan_name as name, xchan_photo_s as micro, xchan_url as url, xchan_addr as nick, 0 as abook_flags, 0 as abook_self
FROM xchan WHERE xchan_deleted = 0 and xchan_network != 'unknown' $sql_extra2 order by $order_extra2 xchan_name asc"
);
if ($r2) {
$r = array_merge($r,$r2);

View file

@ -263,22 +263,24 @@ class Import extends Controller {
);
}
else {
$photos = import_xchan_photo($xchan['xchan_photo_l'],$xchan['xchan_hash']);
if ($photos[4]) {
$photodate = NULL_DATE;
}
else {
$photodate = $xchan['xchan_photo_date'];
}
$photos = import_remote_xchan_photo($xchan['xchan_photo_l'],$xchan['xchan_hash']);
if ($photos) {
if ($photos[4]) {
$photodate = NULL_DATE;
}
else {
$photodate = $xchan['xchan_photo_date'];
}
$r = q("update xchan set xchan_photo_l = '%s', xchan_photo_m = '%s', xchan_photo_s = '%s', xchan_photo_mimetype = '%s', xchan_photo_date = '%s' where xchan_hash = '%s'",
dbesc($photos[0]),
dbesc($photos[1]),
dbesc($photos[2]),
dbesc($photos[3]),
dbesc($photodate),
dbesc($xchan['xchan_hash'])
);
$r = q("update xchan set xchan_photo_l = '%s', xchan_photo_m = '%s', xchan_photo_s = '%s', xchan_photo_mimetype = '%s', xchan_photo_date = '%s' where xchan_hash = '%s'",
dbesc($photos[0]),
dbesc($photos[1]),
dbesc($photos[2]),
dbesc($photos[3]),
dbesc($photodate),
dbesc($xchan['xchan_hash'])
);
}
}
}

View file

@ -104,26 +104,32 @@ class Thing extends Controller {
$orig_record = $t[0];
if($photo != $orig_record['obj_imgurl']) {
delete_thing_photo($orig_record['obj_imgurl'],get_observer_hash());
$arr = import_xchan_photo($photo,get_observer_hash(),true);
$local_photo = $arr[0];
$local_photo_type = $arr[3];
$arr = import_remote_xchan_photo($photo,get_observer_hash(),true);
if ($arr) {
$local_photo = $arr[0];
$local_photo_type = $arr[3];
}
else {
$local_photo = $orig_record['obj_imgurl'];
}
}
else
else {
$local_photo = $orig_record['obj_imgurl'];
$r = q("update obj set obj_term = '%s', obj_url = '%s', obj_imgurl = '%s', obj_edited = '%s', allow_cid = '%s', allow_gid = '%s', deny_cid = '%s', deny_gid = '%s' where obj_obj = '%s' and obj_channel = %d ",
dbesc($name),
dbesc(($url) ? $url : z_root() . '/thing/' . $term_hash),
dbesc($local_photo),
dbesc(datetime_convert()),
dbesc($x['allow_cid']),
dbesc($x['allow_gid']),
dbesc($x['deny_cid']),
dbesc($x['deny_gid']),
dbesc($term_hash),
intval(local_channel())
);
}
if ($local_photo) {
$r = q("update obj set obj_term = '%s', obj_url = '%s', obj_imgurl = '%s', obj_edited = '%s', allow_cid = '%s', allow_gid = '%s', deny_cid = '%s', deny_gid = '%s' where obj_obj = '%s' and obj_channel = %d ",
dbesc($name),
dbesc(($url) ? $url : z_root() . '/thing/' . $term_hash),
dbesc($local_photo),
dbesc(datetime_convert()),
dbesc($x['allow_cid']),
dbesc($x['allow_gid']),
dbesc($x['deny_cid']),
dbesc($x['deny_gid']),
dbesc($term_hash),
intval(local_channel())
);
}
info( t('Thing updated') . EOL);
$r = q("select * from obj where obj_channel = %d and obj_obj = '%s' limit 1",
@ -150,10 +156,16 @@ class Thing extends Controller {
$local_photo = null;
if($photo) {
$arr = import_xchan_photo($photo,get_observer_hash(),true);
$local_photo = $arr[0];
$local_photo_type = $arr[3];
$arr = import_remote_xchan_photo($photo,get_observer_hash(),true);
if ($arr) {
$local_photo = $arr[0];
$local_photo_type = $arr[3];
}
else {
$local_photo = $photo;
}
}
$created = datetime_convert();
$url = (($url) ? $url : z_root() . '/thing/' . $hash);

43
Zotlabs/Module/Xp.php Normal file
View file

@ -0,0 +1,43 @@
<?php
namespace Zotlabs\Module;
use Zotlabs\Web\Controller;
class Xp extends Controller {
function get() {
if (argc() > 1) {
$path = 'cache/xp/' . substr(argv(1),0,2) . '/' . substr(argv(1),2,2) . '/' . argv(1);
if (! file_exists($path)) {
http_status_exit(404,'Not found');
}
$x = @getimagesize($path);
if ($x) {
header('Content-Type: ' . $x['mime']);
}
$cache = intval(get_config('system','photo_cache_time'));
if (! $cache) {
$cache = (3600 * 24); // 1 day
}
header('Expires: ' . gmdate('D, d M Y H:i:s', time() + $cache) . ' GMT');
// Set browser cache age as $cache. But set timeout of 'shared caches'
// much lower in the event that infrastructure caching is present.
$smaxage = intval($cache/12);
header('Cache-Control: s-maxage=' . $smaxage . '; max-age=' . $cache . ';');
$infile = fopen($path,'rb');
$outfile = fopen('php://output','wb');
if ($infile && $outfile) {
pipe_streams($infile,$outfile);
}
fclose($infile);
fclose($outfile);
killme();
}
http_status_exit(404,'Not found');
}
}

View file

@ -36,12 +36,16 @@ class PhotoGd extends PhotoDriver {
}
$this->image = @imagecreatefromstring($data);
if ($this->image !== false) {
$this->valid = true;
$this->setDimensions();
imagealphablending($this->image, false);
imagesavealpha($this->image, true);
}
else {
logger('image load failed');
}
}
protected function setDimensions() {
@ -164,7 +168,7 @@ class PhotoGd extends PhotoDriver {
switch ($this->getType()){
case 'image/webp':
\imagewebp($this->image);
break;

View file

@ -41,7 +41,8 @@ class PhotoImagick extends PhotoDriver {
try {
$this->image->readImageBlob($data);
} catch(Exception $e) {
logger('Imagick readImageBlob() exception:' . print_r($e, true));
logger('Imagick read failed');
// logger('Imagick readImageBlob() exception:' . print_r($e, true));
return;
}

View file

@ -16,7 +16,7 @@ use Zotlabs\Daemon\Run;
* @brief This file defines some global constants and includes the central App class.
*/
define ( 'STD_VERSION', '20.08.25' );
define ( 'STD_VERSION', '20.08.26' );
define ( 'ZOT_REVISION', '6.0' );
define ( 'DB_UPDATE_VERSION', 1241 );

View file

@ -61,6 +61,7 @@ function z_mime_content_type($filename) {
'jpg' => 'image/jpeg',
'gif' => 'image/gif',
'bmp' => 'image/bmp',
'webp' => 'image/webp',
'ico' => 'image/vnd.microsoft.icon',
'tiff' => 'image/tiff',
'tif' => 'image/tiff',
@ -628,7 +629,7 @@ function attach_store($channel, $observer_hash, $options = '', $arr = null) {
$is_photo = 0;
$gis = @getimagesize($src);
logger('getimagesize: ' . print_r($gis,true), LOGGER_DATA);
if(($gis) && ($gis[2] === IMAGETYPE_GIF || $gis[2] === IMAGETYPE_JPEG || $gis[2] === IMAGETYPE_PNG)) {
if(($gis) && in_array($gis[2], [ IMAGETYPE_GIF, IMAGETYPE_JPEG, IMAGETYPE_PNG, IMAGETYPE_WEBP ])) {
$is_photo = 1;
if($gis[2] === IMAGETYPE_GIF)
$def_extension = '.gif';
@ -636,6 +637,8 @@ function attach_store($channel, $observer_hash, $options = '', $arr = null) {
$def_extension = '.jpg';
if($gis[2] === IMAGETYPE_PNG)
$def_extension = '.png';
if($gis[2] === IMAGETYPE_WEBP)
$def_extension = '.webp';
}
// If we know it's a photo, over-ride the type in case the source system could not determine what it was
@ -1470,8 +1473,8 @@ function attach_delete($channel_id, $resource, $is_photo = 0) {
if(! $r) {
attach_drop_photo($channel_id,$resource);
$arr = ['channel_id' => $channel_id, 'resource' => $resource, 'is_photo'=>$is_photo];
call_hooks("attach_delete",$arr);
$arr = ['channel_id' => $channel_id, 'resource' => $resource, 'is_photo'=>$is_photo];
call_hooks("attach_delete",$arr);
return;
}
@ -1548,6 +1551,19 @@ function attach_drop_photo($channel_id,$resource) {
if($x) {
drop_item($x[0]['id'],false,(($x[0]['item_hidden']) ? DROPITEM_NORMAL : DROPITEM_PHASE1),true);
}
$r = q("select content from photo where uid = %d and resource_id = '%s' and os_storage = 1",
intval($channel_id),
dbesc($resource)
);
if ($r) {
foreach ($r as $rv) {
$p = dbunescbin($rv['content']);
if ($p && file_exists($p)) {
unlink($p);
}
}
}
q("DELETE FROM photo WHERE uid = %d AND resource_id = '%s'",
intval($channel_id),
dbesc($resource)

View file

@ -2360,16 +2360,18 @@ function anon_identity_init($reqvars) {
);
$photo = z_root() . '/' . get_default_profile_photo(300);
$photos = import_xchan_photo($photo,$hash);
$r = q("update xchan set xchan_photo_date = '%s', xchan_photo_l = '%s', xchan_photo_m = '%s', xchan_photo_s = '%s', xchan_photo_mimetype = '%s' where xchan_guid = '%s' and xchan_hash = '%s' and xchan_network = 'anon' ",
dbesc(datetime_convert()),
dbesc($photos[0]),
dbesc($photos[1]),
dbesc($photos[2]),
dbesc($photos[3]),
dbesc($anon_email),
dbesc($hash)
);
$photos = import_remote_xchan_photo($photo,$hash);
if ($photos) {
$r = q("update xchan set xchan_photo_date = '%s', xchan_photo_l = '%s', xchan_photo_m = '%s', xchan_photo_s = '%s', xchan_photo_mimetype = '%s' where xchan_guid = '%s' and xchan_hash = '%s' and xchan_network = 'anon' ",
dbesc(datetime_convert()),
dbesc($photos[0]),
dbesc($photos[1]),
dbesc($photos[2]),
dbesc($photos[3]),
dbesc($anon_email),
dbesc($hash)
);
}
}
return $x[0];

View file

@ -346,6 +346,10 @@ function remove_all_xchan_resources($xchan, $channel_id = 0) {
$r = q("delete from hubloc where hubloc_hash = '%s'",
dbesc($xchan)
);
$r = q("delete from xprof where xprof_hash = '%s'",
dbesc($xchan)
);
}
else {

View file

@ -368,8 +368,10 @@ function import_objs($channel, $objs) {
}
if ($obj['obj_imgurl']) {
$x = import_xchan_photo($obj['obj_imgurl'], $channel['channel_hash'], true);
$obj['obj_imgurl'] = $x[0];
$x = import_remote_xchan_photo($obj['obj_imgurl'], $channel['channel_hash'], true);
if ($x) {
$obj['obj_imgurl'] = $x[0];
}
}
create_table_from_array('obj', $obj);
@ -424,8 +426,10 @@ function sync_objs($channel, $objs) {
if ($obj['obj_imgurl']) {
// import_xchan_photo() has a switch to store thing images
$x = import_xchan_photo($obj['obj_imgurl'], $channel['channel_hash'], true);
$obj['obj_imgurl'] = $x[0];
$x = import_remote_xchan_photo($obj['obj_imgurl'], $channel['channel_hash'], true);
if ($x) {
$obj['obj_imgurl'] = $x[0];
}
}
$hash = $obj['obj_obj'];
@ -478,8 +482,10 @@ function import_apps($channel, $apps) {
if ($app['app_photo']) {
// overload import_xchan_photo()
$x = import_xchan_photo($app['app_photo'], $channel['channel_hash'], true);
$app['app_photo'] = $x[0];
$x = import_remote_xchan_photo($app['app_photo'], $channel['channel_hash'], true);
if ($x) {
$app['app_photo'] = $x[0];
}
}
$hash = $app['app_id'];
@ -570,8 +576,10 @@ function sync_apps($channel, $apps) {
if ($app['app_photo']) {
// use import_xchan_photo()
$x = import_xchan_photo($app['app_photo'],$channel['channel_hash'],true);
$app['app_photo'] = $x[0];
$x = import_remote_xchan_photo($app['app_photo'],$channel['channel_hash'],true);
if ($x) {
$app['app_photo'] = $x[0];
}
}
if ($exists && $term) {

View file

@ -1011,7 +1011,7 @@ function import_author_unknown($x) {
if($r && $x['photo']) {
$photos = import_xchan_photo($x['photo']['src'],$x['url']);
$photos = import_remote_xchan_photo($x['photo']['src'],$x['url']);
if($photos) {
$r = q("update xchan set xchan_photo_date = '%s', xchan_photo_l = '%s', xchan_photo_m = '%s', xchan_photo_s = '%s', xchan_photo_mimetype = '%s' where xchan_hash = '%s' and xchan_network = 'unknown'",

View file

@ -4,6 +4,7 @@ use Zotlabs\Photo\PhotoDriver;
use Zotlabs\Photo\PhotoGd;
use Zotlabs\Photo\PhotoImagick;
use Zotlabs\Lib\Img_cache;
use Zotlabs\Lib\Hashpath;
/**
* @brief Return a PhotoDriver object.
@ -33,10 +34,20 @@ function photo_factory($data, $type = null) {
return null;
}
$ignore_imagick = get_config('system', 'ignore_imagick');
$ignore_imagick = get_config('system','ignore_imagick');
if (class_exists('Imagick') && !$ignore_imagick) {
$ph = new PhotoImagick($data, $type);
// As of August 2020, webp support is still poor in both imagick and gd. Both claim to support it,
// but both may require additional configuration. If it's a webp and the imagick driver failed,
// we'll try again with GD just in case that one handles it. If not, you may need to install libwebp
// which should make imagick work and/or re-compile php-gd with the option to include that library.
if (! $ph->is_valid() && $type === 'image/webp') {
$ph = null;
}
}
if (! $ph) {
@ -141,19 +152,35 @@ function guess_image_type($filename, $headers = '') {
function delete_thing_photo($url, $ob_hash) {
$hash = basename($url);
$hash = substr($hash, 0, strpos($hash, '-'));
$dbhash = substr($hash, 0, strpos($hash, '-'));
// hashes should be 32 bytes.
if ((! $ob_hash) || (strlen($hash) < 16)) {
if ((! $ob_hash) || (strlen($dbhash) < 16)) {
return;
}
q("delete from photo where xchan = '%s' and photo_usage = %d and resource_id = '%s'",
dbesc($ob_hash),
intval(PHOTO_THING),
dbesc($hash)
);
if (strpos($url,'/xp/') !== false && strpos($url,'.obj') !== false) {
$xppath = 'cache/xp/' . substr($hash,0,2) . '/' . substr($hash,2,2) . '/' . $hash;
if (file_exists($xppath)) {
unlink($xppath);
}
$xppath = str_replace('-4','-5',$xppath);
if (file_exists($xppath)) {
unlink($xppath);
}
$xppath = str_replace('-5','-6',$xppath);
if (file_exists($xppath)) {
unlink($xppath);
}
}
else {
q("delete from photo where xchan = '%s' and photo_usage = %d and resource_id = '%s'",
dbesc($ob_hash),
intval(PHOTO_THING),
dbesc($dbhash)
);
}
}
/**
@ -189,9 +216,6 @@ function import_xchan_photo($photo, $xchan, $thing = false, $force = false) {
$hash = photo_new_resource();
$os_storage = false;
// $cache_path = Img_cache::get_filename($xchan,'cache/xphoto');
if (! $thing) {
$r = q("select resource_id, edited, mimetype from photo where xchan = '%s' and photo_usage = %d and imgscale = 4 limit 1",
dbesc($xchan),
@ -312,21 +336,21 @@ function import_xchan_photo($photo, $xchan, $thing = false, $force = false) {
}
function import_remote_xchan_photo($photo, $xchan) {
function import_remote_xchan_photo($photo, $xchan, $thing = false) {
// logger('Updating channel photo from ' . $photo . ' for ' . $xchan, LOGGER_DEBUG);
$failed = true;
$hash = hash('sha256', $photo);
$slug = substr($hash,0,2);
$slug2 = substr($hash,2,2);
$path = 'cache/xphoto/' . $slug . '/' . $slug2;
$outfile = $path . '/' . $hash;
os_mkdir($path, STORAGE_DEFAULT_PERMISSIONS, true);
$path = Hashpath::path((($thing) ? $photo . $xchan : $xchan),'cache/xp',2);
$hash = basename($path);
$modified = ((file_exists($outfile)) ? @filemtime($outfile) : 0);
if (strpos($photo,z_root() === 0)) {
// Maybe it's already a cached xchan photo
if (strpos($photo, z_root() . '/xp/') === 0) {
return false;
}
@ -342,20 +366,20 @@ function import_remote_xchan_photo($photo, $xchan) {
if ($result['success']) {
$type = guess_image_type($photo, $result['header']);
if ($type) {
$failed = false;
}
if ($type) {
$failed = false;
}
}
elseif ($result['return_code'] == 304) {
$photo = z_root() . '/photo/' . $hash . '-4';
$thumb = z_root() . '/photo/' . $hash . '-5';
$micro = z_root() . '/photo/' . $hash . '-6';
$photo = z_root() . '/xp/' . $hash . '-4' . (($thing) ? '.obj' : EMPTY_STR);
$thumb = z_root() . '/xp/' . $hash . '-5' . (($thing) ? '.obj' : EMPTY_STR);
$micro = z_root() . '/xp/' . $hash . '-6' . (($thing) ? '.obj' : EMPTY_STR);
$failed = false;
}
if (! $failed && $result['return_code'] != 304) {
$img = photo_factory($img_str, $type);
$img = photo_factory($result['body'], $type);
if ($img->is_valid()) {
$width = $img->getWidth();
$height = $img->getHeight();
@ -389,25 +413,28 @@ function import_remote_xchan_photo($photo, $xchan) {
'edited' => $modified,
];
$r = $img->save($p);
$savepath = $path . '-' . $p['imgscale'] . (($thing) ? '.obj' : EMPTY_STR);
$photo = z_root() . '/xp/' . $hash . '-' . $p['imgscale'] . (($thing) ? '.obj' : EMPTY_STR);
$r = $img->saveImage($savepath);
if ($r === false) {
$failed = true;
}
$img->scaleImage(80);
$p['imgscale'] = 5;
$r = $img->save($p);
$savepath = $path . '-' . $p['imgscale'] . (($thing) ? '.obj' : EMPTY_STR);
$thumb = z_root() . '/xp/' . $hash . '-' . $p['imgscale'] . (($thing) ? '.obj' : EMPTY_STR);
$r = $img->saveImage($savepath);
if ($r === false) {
$failed = true;
}
$img->scaleImage(48);
$p['imgscale'] = 6;
$r = $img->save($p);
$savepath = $path . '-' . $p['imgscale'] . (($thing) ? '.obj' : EMPTY_STR);
$micro = z_root() . '/xp/' . $hash . '-' . $p['imgscale'] . (($thing) ? '.obj' : EMPTY_STR);
$r = $img->saveImage($savepath);
if ($r === false) {
$failed = true;
}
$photo = z_root() . '/photo/' . $hash . '-4';
$thumb = z_root() . '/photo/' . $hash . '-5';
$micro = z_root() . '/photo/' . $hash . '-6';
}
else {
logger('Invalid image from ' . $photo);

View file

@ -126,15 +126,17 @@ function xchan_store($arr) {
}
if($update_photo && $arr['photo']) {
$photos = import_xchan_photo($arr['photo'],$arr['hash']);
$x = q("update xchan set xchan_photo_date = '%s', xchan_photo_l = '%s', xchan_photo_m = '%s', xchan_photo_s = '%s', xchan_photo_mimetype = '%s' where xchan_hash = '%s'",
dbesc(datetime_convert()),
dbesc($photos[0]),
dbesc($photos[1]),
dbesc($photos[2]),
dbesc($photos[3]),
dbesc($arr['hash'])
);
$photos = import_remote_xchan_photo($arr['photo'],$arr['hash']);
if ($photos) {
$x = q("update xchan set xchan_photo_date = '%s', xchan_photo_l = '%s', xchan_photo_m = '%s', xchan_photo_s = '%s', xchan_photo_mimetype = '%s' where xchan_hash = '%s'",
dbesc(datetime_convert()),
dbesc($photos[0]),
dbesc($photos[1]),
dbesc($photos[2]),
dbesc($photos[3]),
dbesc($arr['hash'])
);
}
}
if($update_name && $arr['name']) {
$x = q("update xchan set xchan_name = '%s', xchan_name_date = '%s' where xchan_hash = '%s'",
@ -292,6 +294,21 @@ function xchan_change_key($oldx,$newx,$data) {
}
function cleanup_xchan_photos() {
$r = q("select photo.xchan, photo.resource_id from photo left join xchan on photo.xchan = xchan_hash where photo.xchan != '' and uid = 0 and imgscale = 4 and photo_usage = 2 and xchan_photo_l like ('%s') limit 200",
dbesc(z_root() . '/xp/%')
);
if ($r) {
foreach ($r as $rv) {
q("delete from photo where xchan = '%s' and resource_id = '%s' and photo_usage = 2 and uid = 0",
dbesc($rv['xchan']),
dbesc($rv['resource_id'])
);
}
}
}
function xprof_store_lowlevel($profile) {