Category Archives: Uncategorized

PHP script to batch download from Wallpaperscraft website

I found myself interesting in renewing my wallpapers gallery, and Wallpaperscraft website is really full of themed collections, like, it’s huge!

But then, who’s going to just download every picture by hand, right? Well I know PHP, so one morning when I had the time I jotted down some lines of code.

This script is working at the time of writing, but any change occurring in the source code or in the url structure may break it (not that it would be so hard to fix it anyway).

This is clear to anyone who can run a PHP script, just change the configurable values at the top, the folder name “Wallpapers” in the code, and it’s good to go.

<?php

$webbase="https://wallpaperscraft.com/catalog/city/page";
$imgbase="https://images.wallpaperscraft.com/image/";
$res="_1920x1080";

$i=1;
$c=1;
$goon=true;
while ($goon) {
	echo "\nscarico da $webbase$i\n\n";
	$html=file_get_contents($webbase.$i);
	if (strpos($html,"<html>")===false) {
		$html=gzdecode($html);
		if (strpos($html,"<html>")===false) {
			echo "pagina $i sballata, riscarico...\n";
			sleep(2);
			continue;
		}
	}
	preg_match_all("/<a class=\"wallpapers__link\" href=\"([\/a-z0-9\_]+)\">/",$html,$matches);
	//var_dump($matches);
	if ($matches[1][0]) {
		foreach ($matches[1] as $image) {
			$image=explode("/",$image);
			$image=end($image);
			if (!file_exists("Wallpapers/$image.jpg")) {
				$handle=@fopen($imgbase.$image.$res.".jpg", 'rb');
				if ($handle) {
					echo "$i:$c $image ...\n";
					file_put_contents("Wallpapers/$image.jpg",$handle);
					fclose($handle);
					$c++;
					//https://images.wallpaperscraft.com/image/pier_dock_sea_dusk_shore_118549_1920x1080.jpg
				}
			}
		}
	}
	else {
		$goon=false;
	}
	//sleep(1);
	$i++;
}

Telegram Bot API getUpdates on long polling shorts on 50 seconds

I didn’t want to implement an open HTTPs server for webhooks, even if they look sexy, but I also wanted to load the Telegram servers as little as possible, so given that the long polling doesn’t really get any delay if you arbitrarily increase the timeout*, I setted up a 300 seconds timeout for a 5 minutes refresh of the request.

My getUpdates URL is built like so:

"https://api.telegram.org/bot".$telegrambot."/getUpdates?timeout=".$timeout."&offset=".$offset

where $timeout is set at 300.

What I found out from my PHP app logs is this:

Time | UpdateID | HTTP Response | Total time
20:56:09 455417146 200 50.210294
20:56:59 455417146 200 50.205697
20:57:49 455417146 200 50.18303
20:58:39 455417146 200 50.191815
20:59:30 455417146 200 50.180151
21:00:20 455417146 200 50.178455
21:01:10 455417146 200 50.204421
21:02:00 455417146 200 50.197673
21:02:50 455417146 200 50.193216
21:03:41 455417146 200 50.205001
21:04:31 455417146 200 50.190687
21:05:21 455417146 200 50.178421
21:06:11 455417146 200 50.198388
21:07:01 455417146 200 50.191959
21:07:51 455417146 200 50.190216
21:08:42 455417146 200 50.193751
21:09:32 455417146 200 50.192767
21:10:22 455417146 200 50.189805
21:11:12 455417146 200 50.205147
21:12:02 455417146 200 50.191382
21:12:53 455417146 200 50.191173
21:13:43 455417146 200 50.201623
21:14:33 455417146 200 50.190784
21:15:23 455417146 200 50.189714
21:16:13 455417146 200 50.191169
21:17:04 455417146 200 50.193477
21:17:54 455417146 200 50.199469
21:18:44 455417146 200 50.210404
21:19:34 455417146 200 50.183195
21:20:24 455417146 200 50.178331
21:21:15 455417146 200 50.203791
21:22:05 455417146 200 50.203149
21:22:55 455417146 200 50.190459
21:23:45 455417146 200 50.19248
21:24:35 455417146 200 50.193081
21:25:26 455417146 200 50.180961
21:26:16 455417146 200 50.197347

No matter what timeout value you set in the URL, the server will always return after 50 seconds.

Why oh why?

* you can check on Wikipedia for a long polling description, anyway here’s the hang of it: you load a URL with a set timeout in the query, the webserver accepts the request but doesn’t send back any data until either some updates are found, or the timeout expires. So, for example, if the timeout is 60 seconds, either there’s an update in the next minute, after which the server immediately responds with the update information, or at the 60 seconds mark the server will respond with “no updates”, at which point you can send out an HTTP request again to that URL, and the cycle starts anew. Since there is no real delay between the updates and the server response, it would be sensible to set a high timeout, even 10 minutes, so, while still getting updates as soon as possible, you will load the server very little.

Xiaomi Mi Band 2 vs Teclast H30, first impressions

I had been using the Mi Band 2 foralmost a month, but ordered the Teclast H30 because I liked the SMS text function, and also the general look of it.

What I like of the Mi Band 2 is the fact that I have a watch on my wrist once again (I have been wristwatch-less for about 10 years!), it warns me of incoming calls (when I am working among loud noises or walking to work among traffic, I might not hear my phone or feel it vibrating inside my pocket) and the sleep tracking function.

Heartrate measurement is a disappointment, but not because of Mi Band 2 in itself, more that as a technology you need to stay really in one place and not moving, otherwise it WILL miss hearbeats and give you a really low frequency. Also you do not get continous heartrate measures with the Mi Band 2.

Distance and calories are so useless since they are calculated based on steps count, and amount to a really insignificant number.

When I got the Teclast H30 I put them together on the same wrist. Pairing the band with my phone was a blast (with the Mi Band 2 it took WAY too much fiddling with my phone’s bluetooth).

Surprise, Teclast H30 supports continuous heart rate measurement via a setting on the Android app, but the value was inaccurate if compared to Mi Band 2 (I was fast walking back home, Mi Band 2 gave me a realistic 139bpm, while the H30 was stuck at max 93, but it might as well have been a defect in positioning it on my wrist).

Also Teclast H30 over Mi Band 2 has the find my phone function, where you would jump to said function and your phone would ring.

Also Teclast H30 often was faster than Mi Band 2 in showing the time after raising my wrist.

TSports app doesn’t require online registration as MiFit does.

The advantages though end right about at this point.

I could greenify MiFit app, but TSports is hard to be put in hibernation as it installs as a resident app by default and eats away at the phone battery even if it is in the watchlist of Greenify.

You cannot choose which elements to display on Teclast H30 like you can with the Mi Band 2, you always have to scroll through the Time/Date/Sleep hours/Steps/Distance/Calories/Battery/Find Phone, and it gets annoying really fast! Also on the Mi Band 2 you can display, with the latest firmware, time and date together, while on Teclast H30 they are on different screens.

Finally, the alarms: on MiFit you can set alarms depending on the weekday or just once, while on TSports you can only set an alarm to ring every day for the rest of existence.

I cannot report about sleep tracking nor battery duration as after a half-a-day experience I gave this band to my S.O.

I can testify anyway on the SMS text display to be working, as I got one during that time. It doesn’t display the author name even if it is in your phonebook though, just the originating phone number.

That’s all folks!

Revert, undo & go back from adoptable to portable storage in android marshmallow

I replaced my previous 32GB microsd in my note 3, with a transcend 64GB, and the system asked me if I wanted to use it as extended internal storage. Why not, I never use the sd as swappable storage anyway, and I liked the encrypted storage.

Go ahead an hour, I notice the system filled up 30GB more than the starting space, just stealing it from the sd card for no reason. Also, after rebooting I get a message saying “system has stopped responding”, and swiftkey cannot load languages anymore, disabling altogether the swype function.

Great!

I fiddle for good 15 minutes into the settings, finding nothing apparent, until I went into:

Settings > USB and Storage > Internal storage > Options > Migrate

which was supposed to migrate the data from the sd back into the builtin storage.

I started the process and went to sleep (it was late) hoping to find it solved in the morning… too bad! Couldn’t do that, the morning after the internal storage was 100% filled, an error message appeared, and the 60GB sd was still hald full.

The system went from the original 16GB used in the internal storage, to a total of 30GB filled internal storage+roughly 30GB inside the external, which is 60GB used storage… for what? God knows! In the USB&Storage panel of the settings, the details of the used space still amounted to the real space needed, and nothing was there to account for the additional space taken that was reported in the summarized stats…

Hence, I tried copying all the contents from the sd/internal storage to the PC, with the intention of resetting everything afterwards and restoring the data, but using the USB communication resulted in a severely slow transfer speed (we’re talking about a 100Kb file each few seconds, and there were 12GB of data to move).

I tried several times to check and see if I could speed things up, to no avail, so I used the remaining free space on the microsd (I had that, if you don’t you may want to use an OTG cable and a pendrive) to create a ZIP archive (with estrongs) of all the contents of the internal storage, and as a single file like that I could then copy it to my PC at a decent speed.

Once that was done, I wend in settings > USB and storage > SD card > options > format as portable, agreeing to lose all data (I had backed it up anyway), then into recovery I wiped the internal storage, then rebooted to have the changes take effect, and from this state (internal storage almost empty, microsd seen as normal portable storage) I copied over the backed up contents from the previous configuration via normal USB transfer (some files and folders couldn’t be copied, but it was nothing essential).

Up until now eveything looks to have gone back to normal.

phpBB: set gravatar as default for new users

Self reference: edit /includes/function_user.php as follows:

'user_avatar'         => strtolower($user_row['user_email']),
 'user_avatar_type'      => 'avatar.driver.gravatar',
 'user_avatar_width'      => 60,
 'user_avatar_height'   => 60,

also edit /phpbb/avatar/driver/gravatar.php and change:

$url .= '?s=' . max($row['avatar_width'], $row['avatar_height']);

into:

$url .= '?s=' . max($row['avatar_width']."&d=identicon", $row['avatar_height']);

so users who are not registered with gravatar get an automatically generated icon istead of mystery man.

Dominant color of image as background of DIV, all in CSS

I was trying to do something fancy, and have a grayscale image turned into colored mode on mouse hover, together with showing a popup… and I obviously wanted the popup background color to be related to the image that had just been coloured up.

There is a precise javascript function that does that, it’s the color thief plugin for jQuery. Other than needing javascript to achieve the result (which may be fine), it wasn’t viable in my situation because it cannot work cross-domain with images stored on a different website from the one calling the javascript.

My original idea was to have it all done in CSS anyway, so a bright idea popped into my mind: why not using the browser itself to find the dominant color? And when does the browser find the dominant color of an image? When you resize it to 1pixel x 1pixel.

So…

background-image:url(yourimage);
background-size: 1px 1px;

that’s all for the basics.

If you want to make the colour stand out more, but only in non Internet Explorer browsers (thank you Microsoft) then to those declarations you can add:

-webkit-filter: saturate(5);
filter: saturate(5);

You obviously have to insert this code in the relevant place of your page… be it with hardcoded values (but if they were, wou wouldn’t be here asking how to DINAMICALLY find the dominant colour of an image) or with PHP or anything else in the backend directly inside a style="..." CSS statement inside the HTML tag.

The background colour may be too dark for black text, or too bright for white text depending on the image, so unless you want to apply an ugly text-shadow all around the characters to make them always readable (not so much actually, unless you’re using huge fonts), you may want to have a container DIV with a couple of DIVs inside, one holding the background, with half opacity, and the other containing the text, both with 100% width and height, and absolutely positioned to top:0;left:0; inside the container, maybe with a z-index:-1; on the background div.

Have fun!

403 Permission denied on Apache in Debian/Ubuntu with changed document root

I had just made a brand new installation of both Ubuntu trusty and vivid and Debian jessie (tried all of them) on my android phone with Linux Deplow, and installed the LAMP stack via SSH. I wanted Apache to serve files decrypted from an EncFS mount, so I found easier to move the DocumentRoot to a subfolder of my home (by editing /etc/apache2/sites-available/000-default.conf – by the way, this file has changed location quite a bit in the past, being called just default.conf, or being httpd.conf in older versions), and changed Apache’s username to my own (by editing /etc/apache2/envvars).

Well, what happened is that, no matter what I did, I was still getting a 403 Permission denied error, which had nothing to do with EncFS.

By pure chance, I went checking what was inside /etc/apache2/apache2.conf, and other than a reference to envvars for the username and group definitions for the user Apache is run as, scrolling further down there are folders definitions which were, in previous versions, located in the default.conf file. Changing in there the reference to /var/www into the new custom folder made it.

You obviously need to restart Apache after such changes.