Home photo server, part 2: Apache, phpAlbum, and Piwigo

Last time we talked about how to set up the domain name with DDNS for free, and then using very secure FTP, vsftp, and SyncTool (the Android app) to automatically move photos from your phone to your home server. But that’s only half of the battle. One of the big perks to using Google Photos is that you can browse them anytime from anywhere. You can share them with friends, make comments on them, and other socially related things. We need a way to do that from our home server, too.

There are many, many methods to accomplish this, and I tried several, but I’d like to point out two options that worked really well, were simple to use and set up, and used little to no JavaScript. There are several reasons why one might not want to use JS, like security, etc., but I’ll save that for another post. The two best options were phpAlbum, which is 100% JS free, and Piwigo, which only uses JS for some display themes, I chose one without it and it seems to work just fine.

Either way, I needed a web server, so I installed Apache.

# yum install httpd

# systemctl enable httpd

#firewall-cmd –add-port=80/tcp

# firewall-cmd –add-port=80/tcp –permanent

Right out of the box, you could browse to my web server. Of course, it was insecure and it only displayed the main page. I’ll break down adding certs and making it TLS and SSL compliant in another post. I was ready to set up my router, make sure you route that traffic to your server! Since that is rather router specific, you’ll have to look that up on your own, but there are tons of guides on it. Now it was time to install a photo gallery web server.

So, first on the list, I tried phpAlbum. It worked great and seems to be a good fit, provided that you have a smaller photo collection. One big plus is that it doesn’t need a MySQL database or anything. The only downside: once I surpassed 8000 photos, and numerous folders, it seemed to not be able to keep up. So, for a short time I got around this by setting up multiple web pages, each running a unique instance of phpAlbum, each with it’s own set of photos. This was simple, really, I made one for a couple of years worth, and one for the next 3 or 4 years, and then had a main web page that linked to the different ones. This is a bit tedious and cumbersome though, but wasn’t too bad if you have a lot of static images.

Since it is so simple, and has a good installation guide, which you can read here, I’ll be very brief about how I set this up. You can also click here for a phpAlbum demo.

# yum install php php-xml php-mbstring php-gd

# yum install ImageMagick

# yum install unzip zip

After downloading the latest phpAlbum zip from their website, unzip it and edit config_change_it.php to your needs with nano or vi, basically by setting the data directory and the photo directory, and rename it config.php. Now copy the entire directory to /var/www/html. So in my setup, it was /var/www/html/phpAlbum/ with all of the files in it.

Next, chmod 777 the cache, data, and photo directory inside your folder, so you can write to it with other users (the uploading functions). Then:

# chown -R apache:apache /var/www/html/phpAlbum

so your web server can own it (since I’m using Apache as the web server). Now all you have to do is navigate to http://yourDomainNameIPaddress/phpAlbum and you will be greeted by a login, to which the default is admin and admin for the username and password. Once your in, it will ask you a few questions, and you can be up and running in a few minutes! It worked really great, like I mentioned earlier, when I had a smaller photo collection (under 8000 for me, but your mileage may vary).

Since it was struggling with more photos, I decided to switch to Piwigo. You can check out a demo of it here. There is a really, really great guide on TecMint, that I drew from when putting this together, but it was relatively simple. Start by installing the dependencies – note that a lot of these were already installed for phpAlbum, and I’m not 100% sure you need all of these, but this is what I installed:

# yum install php php-xml php-mbstring php-gd wget unzip zip ImageMagick python python-tk python-psyco mariadb-server php-mysqlnd

Now you need to enable and set up your MySQL/mariaDB:

# systemctl enable mariadb

# mysql -u root -p
MariaDB [(none)]> create database piwigo;
MariaDB [(none)]>grant all privileges on piwigo.* to ‘piwigouser’@’localhost’ identified by ‘pass123’;
MariaDB [(none)]>flush privileges;
MariaDB [(none)]>exit

# systemctl restart httpd

Be sure to use your own usernames and passwords. I don’t recommend the defaults! Then you need to download Piwigo and unzip it, placing it in your Apache web server root directory. After you put it in place, you need to set the proper read and write permissions, as well as ownership:

# wget http://piwigo.org/download/dlcounter.php?code=latest -O piwigo.zip
# unzip piwigo.zip
# cp -rf piwigo/* /var/www/html/
# chown -R apache:apache /var/www/html/
# chmod -R 755 /var/www/html/
# chmod -R 777 /var/www/html/_data/

# systemctl restart httpd
# systemctl restart mariadb

Now it’s up to you how you want to handle moving the pictures we automatically uploaded to the server into the Piwigo directory. For instance, you can have your photos upload from your phone to your home directory, and then make a cron job or script, or manually put them into your Piwigo directory. One benefit of this is deleting blurry or useless photos. I like this option best, but that’s my opinion.

Another option is to set the /var/www/html/galleries photo permissions to be writable/readable by others, or add your user to the group and upload your photos directly to it. I tried this as well, and it works good, too. Either way, now all you have to do is use your web browser to navigate to your server, and you should see the Piwigo first login/setup screen.

Choose your options, such as language, etc., tell Piwigo what the MySQL/MariaDB is called and what that password is, and you should be up and running in no time! Now you can log into the web interface as the admin user (that you just set) and start choosing themes, uploading photos with the web app, or syncing the galleries folder for the photos you put there via FTP or moved manually or scripted.

piwigoPublic

In this screenshot, you can see the light theme that I went with, and how there are some photos available for the public to see. If I log in, then I can see the rest of the pictures:

piwigoPrivate

You can have more users and give each user access to certain files, folders, or groups. Groups is nice because you can give “family” the option to see this, and “friends” the option to see that. You can control everything from the web admin screen:

piwigoAdmin

Another plus to Piwigo is that there are several Android apps out there, some paid, some free, some open source. So there are options, but quite honestly the web browser of Android works great, since Piwigo has two theme settings, one for desktop browsing, and one for mobile browsing as well. So you can have two different themes, one for each desktop and mobile, to maximize what works best for you.

There’s still a few things to cover though. Right now, it is only using port 80 for unsecure web traffic. We definitely want to use secure http on port 443, so we will cover certificates and security next.

Linux – keep it simple.

Advertisements

Android meets Arduino!

As you guys know, I don’t really do “product reviews”. But if I find a handy tool, and use it, then it is fun to share that info with others. One such tool is Bluino Loader, an Android app that lets you create Arduino files, upload them to your boards, and even monitor the serial connection over USB. It’s pretty handy!

As with any “code from your phone app”, it is a bit tedious to type a lot of code with the Android keyboard. So I don’t use this app a lot when it comes time to create code. One of the big things that I like to do with it, though, is to monitor the serial output over a USB OTG cable.

Using the OTG cable, I can hook the Arduino Uno board directly to the phone, which also powers the board. Then I can open up Bluino Loader and click the icon at the top to monitor the serial connection. It can’t get much simpler than that. Within seconds I have serial data coming in and being displayed in the terminal. I even used it to test out the 433 MHz transmit and receive functions from my last test project. Worked like a charm!

Linux – keep it simple.

Android Remote Control through ADB

Today, I stumbled on perhaps the most ingenious use of ADB ever:

Remote control your Android phone through adb

A program and write-up by Marian Schedenig, that they shared on their website. This is perhaps the best adb tool I have ever seen, in that it takes three simple principles and puts them together to allow you to remote control your phone over ADB with your mouse, without ROOT permission!

output3

Here is a small gif that I put together from a screen recording of me using this awesome java tool. Essentially, it uses adb to take screen shots of the phone. Then it downloads the screen shot and updates it’s display. Finally, when you click on the screen, it sends an x/y co-ordinate to the phone over adb to tell it you swiped or clicked! It is absolutely brilliant!

The updates are a little slow, and you do have to edit the config file for your specific needs, but it works great, and is a really useful tool if you broke your screen or have touch screen issues, or just need to display your screen for an audience to view while you press buttons or work with apps. Since it is written in java, it is cross platform as well!

Linux – keep it simple.

Text field types to capitalize sentences…

device-2018-09-10-130014

I recently received a comment from a Just Notes user about how much they loved the simplicity of the notes app. However, they also pointed out that the text field that you type into doesn’t automatically capitalize sentences or names, and somewhat lacks a bit in terms of use.

He was right.

I typically use this for typing grocery lists, and things that don’t turn out to be complete sentences. So I noticed, but it didn’t really matter to me. I realize that others may use it differently, so I wanted to fix this.

So I did.

You can check out the commit here, where I updated to the target api of 26 (per Google’s requirements to be listed on the Play Store now – *sigh*) and changed the text field type. Here is the only thing that actually changed in my app, from this:

android:inputType=”textMultiLine”

to this:

android:inputType=”textCapSentences|textAutoCorrect|textAutoComplete|textMultiLine” />

And that’s it. That makes it work with auto correct, auto complete, and to capitalize sentences!

Linux – keep it simple.

Triple check that, will ya?

device-2017-03-08-124806A long long time ago
I can still remember how
That App used to make me smile….
And I knew if I had my chance
That I could make those dice dance
And maybe they’d be happy for a while….

Uh, wrong lyrics. Actually, it was quite a while ago that I made the Android app, Ships, Captain, and Crew! After the move from GitHub to GitLab, I decided to look over some of my old issues that were imported with GitLab’s great import tool. Among them, I found two issues for this old app that I had made.

The first was that of an issue with screen rotation causing the app to restart. I quickly fixed that by just setting the activity to portrait mode in the manifest file. You can check my commit if you need details.

The second issue was a bit more complicated, in that there was a problem with checking the dice for a ship, captain, or crew. Essentially, if you rolled a 4, 5, 6, 1, and 3, it would say you only have a ship (the 6) and no captain (5) or crew (4). Obviously that’s wrong. The issue is that you need a 6 before you can keep a 5 or 4. And since the dice were checked in order, when it looked at the 5 or 4, it did not have a 6 yet, so they were not “kept”.

This is how I fixed it:

for (int i = 0; i < 3; i++) {

// Check three times.

myNumber = firstDie;

diceCheck();

if (waschecked){

firstnotchecked = false;

}

dieOne.setImageResource(id);

myNumber = secondDie;

diceCheck();

if (waschecked){

secondnotchecked = false;

}

dieTwo.setImageResource(id);

myNumber = thirdDie;

diceCheck();

if (waschecked){

thirdnotchecked = false;

}

dieThree.setImageResource(id);

myNumber = fourthDie;

diceCheck();

if (waschecked){

fourthnotchecked = false;

}

dieFour.setImageResource(id);

myNumber = fifthDie;

diceCheck();

if (waschecked){

fifthnotchecked = false;

}


dieFive.setImageResource(id);


}

As you can see,  I told it to check the dice, first to last, three times. Yes, this is ugly and poor programming. Actually, I was almost ashamed of this early work, it looked so congested and terrible. However, my goal today was the quick fix, so that’s what I did. Hopefully, the update will be available on F-Droid soon, so you’ll have to check it out!

Linux – keep it simple.

Game restarts when minimized!

When I originally created JustChess, I had a problem. If you were playing a game, and pressed the new game button, then started another game, you could press back and go back to the menu, then back and go back to the game. This was a bit odd. At the time, I solved it with “Intent.FLAG_ACTIVITY_NO_HISTORY”. This worked great. Too great.

The problem, as pointed out on my issue tracker, was that when you minimized the game, it would be “destroyed” and rebuilt when you brought the app back. Which is not cool. You may need to answer a text and then come back to your game, and it shouldn’t disappear in between!

minimized

So, I fixed it with my latest commit. I took out the FLAG_ACTIVITY_NO_HISTORY intents, but then my original problem returned. To solve that, I added “finish()” to my new game button, like so:

// First you define it.
Intent myintent = new Intent(MainActivity.this, IntroActivity.class);
// Now you call it.
startActivity(myintent);
finish();

}
})

Now, when you select a new game, it “finishes” your old one. Pressing the back button doesn’t lead you on a wild goose chase to dozens of old games, it just brings you back to the main menu, and that’s much better!

Linux – keep it simple.

JelloStorm.cpp:198:58: error: ?createBackground? was not declared in this scope

grass

After the rough time I had completing section 6 of the course, I was not looking forward to section 7. However, it turned out that section 6 was just tough, and section 7 was pretty easy. That doesn’t mean I didn’t have any trouble though.

alaskalinuxuser@alaskalinuxuser-OptiPlex-7010:~/Documents/c++/Cpp_training/JelloStorm$ ./build.sh
JelloStorm.cpp: In function ?int main()?:
JelloStorm.cpp:198:58: error: ?createBackground? was not declared in this scope
int tileSize = createBackground(tileBackground, arena);
^

Turns out when you make a header file, you have to be sure to include it! Yes, I forgot that line, so I fixed it as such:

#include <SFML/Graphics.hpp>
#include <sstream>
#include <SFML/Audio.hpp>
#include <Player.h>
#include <JelloStorm.h>

And now that it is fixed, my archer has a nice grassy field to walk around in! You can check out the game thus far or the commit at my GitLab!

Linux – keep it simple.

Can’t play chess in landscape mode!

Another one of the great issues brought up by a user of JustChess, my simple chess playing Android app, was the fact that when the screen was rotated, you can’t see the bottom half of the board!

Realistically, this would require one of two things:

  1. Fixed portrait mode, not allowing the user to rotate the screen.
  2. Having a separate layout that was appropriate for the rotated screen.

But instead I chose option number 3: Add a scroll view!

Option 1 would limit users from being able to hold their phone a different way if it was more comfortable, and that doesn’t solve any problems, it just limits use.

Option 2 is the proper way to fix this, but I’m done working on this app right now, and involved in other project. This would be a bit of an overhaul, and would take me a considerable amount of time.

Option 3, is cheating. I am adding a scroll view so that the user who wants to play in landscape view can scroll the board to recenter it on the screen. This is fine for hi-res screens we see today, but may be a problem on an older phone, where the user would have to scroll the board back and forth to see all of it.

slide

Either way, you can see the full commit on my GitLab, but here is the pertinent part of the code, in the layout xml file:

<ScrollView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content">

    <LinearLayout
...... edited for space .......
    </LinearLayout>
</ScrollView>

This neatly wraps everything up into a nested scroll view which the user can move by swiping. This may also help if in portrait mode on an older phone with a very small screen.

Linux – keep it simple.

The game restarts on screen rotation!

After my JustChess app hit the F-Droid repository, I was pleasantly surprised to hear that people were trying it out! With every wave of players, however, came a new wave of issues. I like issues. I’m a bit of a problem solver, so it gives me a clear direction to work towards.

One of the issues was that rotating the screen caused the current game to be destroyed and restarted. Of course! I should have thought about that. Since I sold my Android phones, I was using the emulator to finish building this game. With the emulator, I didn’t consider screen rotation!

Fortunately, the first fix is pretty simple. If your activity restarts on rotation, then you should add this line to your manifest for each activity:

android:configChanges="orientation|screenSize"

Like this:

<activity
    android:name=".MainActivity"
    android:configChanges="orientation|screenSize"
    android:label="@string/app_name"
    android:theme="@style/AppTheme.NoActionBar" />

You can check out the full commit on my GitLab, but that is all you need to fix this issue. Now I just need to make it playable when the screen is rotated!

rotating

Linux – keep it simple.

Cancel all notifications!

While trying to update and add features to my old open source Hourglass app, I decided that the issue posted asking for a notification cancel button was a pretty good idea!

Screenshot from 2018-05-02 13-12-03

Now you can cancel your timer at any time from the notification bar! The code was pretty simple, actually, and you can read the entire commit on my GitLab, but here is the important part:

// as a result of notification action
Intent detailsIntent = new Intent(MainActivity.this, CancelActivity.class);
detailsIntent.putExtra("EXTRA_DETAILS_ID", 42);
PendingIntent detailsPendingIntent = PendingIntent.getActivity(
      MainActivity.this,
      0,
      detailsIntent,
      PendingIntent.FLAG_UPDATE_CURRENT
      );

NotificationCompat.Builder builder = new NotificationCompat.Builder(context)
        .setSmallIcon(R.drawable.hourglass).setWhen(System.currentTimeMillis()+recureTime).setUsesChronometer(true)
        .setContentTitle("Hourglass").setContentText(intentPhrase).addAction(
                android.R.drawable.ic_notification_clear_all, "Cancel", detailsPendingIntent);

Intent intent = new Intent(context, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent pIntent = PendingIntent.getActivity(context, 0 , intent, PendingIntent.FLAG_UPDATE_CURRENT);

This mumbo jumbo just allows the cancel button to be displayed, which, if pressed, calls the CancelActivity class.

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    // Set the screen orientation to portrait to keep the screen rotation bug from stoping
    // the timer on some phones.
    setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);

    // Just log.
    Log.i("WJH", "CancellAll.");
    allCancel = true;
    finish();

}

The moment the CancelActivity.java class opens, it set’s the boolean allCancel to true (meaning yes, we want to cancel) and exits back to the MainActivity class, where the timer is running.

Then, on every tick of the timer, it checks to see if allCancel is true or false. If true, it cancels the timer, repeating timer, and recurring alarm. If false, it continues to count down as usual. Praise God! It actually works! Be sure to check out revision 1.9 of the app for this latest feature! And thanks to “brunetton” for the great idea!

Linux – keep it simple.