KFile, a simple download-link generator for Wordpress

March 10th, 2008

After finally finding a nice CMS to use for my homepage, I was searching for a simple plugin that lets me

  • upload files manually using scp or other means from the command line
  • display a nice link to the file, stating name, size etc. after adding a text like [file=foo.tar.bz2]

All I found were quite large plugins using databases, using quite elaborate administration front ends. So I started writing one myself.

Usage

  • Install and activate the plugin.
  • Create a directory wordpressurl/download (alternatively, change the constant in kfile.php)
  • Upload files there

Synchronizing Digikam and NGG

March 6th, 2008

This little script automatically generates the gallery on this site from the local digikam(kde 3) database. To accomplish that task, it looks for files tagged public, and uploads them if they aren’t already uploaded. It completely rewrites the ngg database, so don’t use this if yo have put effort into creating a database with the ngg frontend.
Pictures are resized locally using imagemagick, so it avoids problems with low memory on some shared servers.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
#!/usr/bin/python
"""
Script to export Photos from Digikam to NGG
Copyright (C) 2008  Andreas Goelzer
 
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
 
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.
 
You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 
This program exports pictures from your 
DigiKam (http://www.digikam.org/) database to a
NGG (http://alexrabe.boelinger.com/category/nextgengallery/) database.
It is at the moment highly experimental and in a works-for-me-right-now
state.
Be really really careful if trying to use it, it will
- determine which photos are tagged "public"
- upload them to a dir, kill everything in the target dir not tagged public
- rewrite the remote database
- automatically create thumbnails along the way
I don't know much about databases, so this code is quite inefficient. It
doesn't pose a big problem for my ~5k local, 100 remote photos, though
 
Once again, it *will* erase the remote directory, and possibly more. 
NO WARRANTY!
see http://andreas.goelzer.de/synchronizing-digikam-and-ngg for updates.
"""
import sqlite3;
import os;
import sys;
import re;
 
print "Calculating new remote DB"
 
con = sqlite3.connect("digikam3.db")
target = "www.domain.de@ssh.strato.de"
targetdir = "subdir"	
openmysql = "mysql -h rdbms -u username --password=pw database"
 
def mymask(obj):
	if type(obj) in (str, unicode):
		return "\'" + obj.replace('"', '\\"').replace("'", "\\'").replace("\n","\\n") + "\'"
	else:
		return repr(obj)
def myrepr(obj):
	str=""
	if type(obj) in (tuple, list):
		for elem in obj:
			str += mymask(elem) + ",";
		return "(" + str[:-1] + ")"
	else:
		return repr(obj)
 
 
def joinselect(con, query):
	return ",".join(list(myrepr(row) for row in con.execute(query)))
 
 
def remoteexec(cmd):
	os.system("ssh " + target + " \"" + cmd + "\"")
 
def copyremote(file,tsubdir):
	os.system("scp -p " + file + " " + target + ":" + re.escape(targetdir + tsubdir));
 
dbprefix = "wp_ngg_"
chooseidsstring = "(SELECT DISTINCT imageid FROM imagetags WHERE tagid = (SELECT id FROM tags WHERE name = \"public\"))"
sqlcommands  = "DELETE FROM " + dbprefix + "pic2tags;\n";
sqlcommands += "DELETE FROM " + dbprefix + "tags;\n";
sqlcommands += "DELETE FROM " + dbprefix + "pictures;\n";
sqlcommands += "DELETE FROM " + dbprefix + "gallery;\n";
sqlcommands += "DELETE FROM " + dbprefix + "album;\n";
 
 
 
 
sqlcommands += "INSERT INTO " + dbprefix + "pic2tags(picid,tagid) VALUES " + joinselect(con, "SELECT  imageid, tagid FROM imagetags  WHERE imageid IN  " + chooseidsstring) + ";\n"
 
sqlcommands += "INSERT INTO " + dbprefix + "tags(id, name, slug) VALUES " + joinselect(con, "SELECT  id,name,name FROM tags WHERE id IN (SELECT DISTINCT tagid FROM imagetags   WHERE imageid IN    " + chooseidsstring + ")") + ";\n"
 
sqlcommands += "INSERT INTO " + dbprefix + "pictures(pid, galleryid, filename, description) VALUES " + joinselect(con, "SELECT  id,dirid,name,caption FROM images   WHERE id IN "  + chooseidsstring ) + ";\n"
 
 
sqlcommands += "INSERT INTO " + dbprefix + "gallery(gid, name, path, title,previewpic) VALUES "
 
 
allalbums="";
j=0;
for row in con.execute("SELECT id,url,icon FROM albums WHERE id IN (SELECT DISTINCT dirid FROM images WHERE id IN " + chooseidsstring + ") ORDER BY url"):
	allalbums += "i:" + str(j) + ";i:" + str(row[0]) + ";"
	j += 1
	#if(row[2] == None): icon = "NULL"
	#check whether icon is public
	icon = str(row[2])
	if(row[2] == None or con.execute(chooseidsstring[1:-1] + " AND imageid = " + icon).fetchone() == None):
		nrow = con.execute("SELECT id FROM images WHERE id IN " + chooseidsstring + " AND dirid = " + str(row[0])).fetchone()
		icon=str(nrow[0]);
	sqlcommands += "(" + str(row[0]) + ", \"" + os.path.basename(row[1]) + "\" , \"photos" + row[1] + "\", \""+ os.path.basename(row[1]).replace("_"," ") + "\"," + icon + "),"	
 
sqlcommands = sqlcommands[:-1] + ";\n"
allalbums = "a:" + str(j) + ":{" + allalbums + "}"
 
sqlcommands += "INSERT INTO "+ dbprefix + "album(id, name, sortorder) VALUES (1, 'Main Gallery', '" + allalbums + "');\n"
 
#print s
f = open('remotedb.sql','w')
f.write(sqlcommands.encode('latin-1'))
f.close()
 
copyremote('remotedb.sql','')
remoteexec(openmysql + '<' + targetdir + '/' + 'remotedb.sql')
 
#exit()
 
print "creating remote directories"
#remotely create dirs
con2 = sqlite3.connect(":memory:")
 
con2.execute("CREATE TABLE remotedirs (file varchar(255), PRIMARY KEY (file))")
a = os.popen("ssh " + target + " find " + re.escape(targetdir) + " -type d").readlines();
 
for elem in a:
	if(elem != ''): con2.execute("INSERT INTO remotedirs VALUES (\"" + elem[len(targetdir):-1] + "\")");
con2.execute("CREATE TABLE localdirs (file varchar(255))")
 
for row in  con.execute("SELECT DISTINCT albums.url from images INNER JOIN albums ON images.dirid = albums.id WHERE images.id IN " + chooseidsstring):
	dirs=row[0].split("/")
	dire=""
	for dirss in dirs[1:]:
		dire += "/" + dirss
		con2.execute("INSERT INTO localdirs VALUES (\"" + dire + "\")");
	con2.execute("INSERT INTO localdirs VALUES (\"" + row[0]+"/thumbs\")");
#delete dirs
for row in con2.execute("SELECT file FROM remotedirs WHERE file NOT IN (SELECT DISTINCT file FROM localdirs) ORDER BY length(file) DESC"):
	print "deleting " + row[0]; 
	remoteexec("rmdir " + re.escape(targetdir + row[0]));
 
#create dirs
for row in con2.execute("SELECT file FROM localdirs WHERE file NOT IN (SELECT file FROM remotedirs)"):
	print "creating " + row[0]; 
	remoteexec("mkdir " + re.escape(targetdir + row[0]));
 
 
 
#handle files
a = os.popen("ssh " + target + " find " + re.escape(targetdir) + " -type f").readlines();
con2.execute("CREATE TABLE remote (file varchar(255), PRIMARY KEY (file))")
for elem in a:
	if(elem != ''): con2.execute("INSERT INTO remote VALUES (\"" + elem[len(targetdir):-1] + "\")");
con2.execute("CREATE TABLE local (file varchar(255), isthumb bool , PRIMARY KEY (file))")
 
for row in  con.execute("SELECT albums.url, images.name from images INNER JOIN albums ON images.dirid = albums.id WHERE images.id IN " + chooseidsstring):
	con2.execute("INSERT INTO local VALUES (\"" + row[0]+"/"+row[1] + "\", 0)");
	con2.execute("INSERT INTO local VALUES (\"" + row[0]+"/thumbs/thumbs_"+row[1] + "\", 1)");
 
print "Deleting leftover files"
#delete files no longer in the db
for row in con2.execute("SELECT file FROM remote WHERE file NOT IN (SELECT file FROM local)"):
	print "deleting " + row[0]; 
	remoteexec("rm " +  re.escape(targetdir + row[0]));
 
print "Uploading files"
#upload files
for row in con2.execute("SELECT file,isthumb FROM local WHERE file NOT IN (SELECT file FROM remote)"):
	if(row[1]):
		print "creating and uploading thumbnail: " + row[0]; 
		os.system("convert \"." + row[0].replace("thumbs/thumbs_","") + "\" -thumbnail 100x75 thumb.jpg")
		copyremote("thumb.jpg", re.escape(row[0]))
	else:
		print "resizing and uploading image:     " + row[0]; 
		os.system("convert \"." + row[0] + "\" -resize \"1024x768>\" small.jpg")
		copyremote("small.jpg", re.escape(row[0]))

filetype uploader.py (7.25 kiB, 2008-10-06)


Deleting multiple tables with a common prefix

March 4th, 2008
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?php
//Connect to the database server and select our database
$link = mysql_connect('rdbms.strato.de', 'UXXXX', 'epsilon eridani') 
	or die('Could not connect: ' . mysql_error());
mysql_select_db('DBXXXX') or die('Could not select database');
 
//get table list
$result = mysql_query("SHOW TABLES") or die(mysql_error());
 
//kill tables
$tokillprefix = "jos_";
while($row=mysql_fetch_array($result)){
 	if(substr($row[0],0,strlen($tokillprefix)) == $tokillprefix){
	 	echo "killing $row[0] <br>\n";
		mysql_query("DROP TABLE $row[0]") or die(mysql_error());
	}
}
 
?>done

Debian Sarge GNU/Linux on a Fujitsu-Siemens Amilo M7425 Laptop

February 29th, 2008

Abstract

This is my Guide to a working Installation of Debian Sarge GNU/Linux on the Amilo M7425. It may be useful for other distributions too, i used a kernel.org 2.6.10 kernel. I’m not yet finished, but it runs well enough. If you are using Suse, check out the Lugoland Amilo M7425 manual. Since I don’t use debian any more, this page wo’t be updated again.

Some notes to Ubuntu

I recently switched to ubuntu. I was impressed how fine this machine works with ubuntu, no need for a selfcompiled kernel, WLan works during the installation process. All I had to do was adding "ac", "battery", "speedstep_centrino" and "cpufreq_ondemand" to /etc/modules and activate my little speedstep script ("update-rc.d speedstep defaults").

Linux and the BenQ/Siemens S81 phone

February 29th, 2008

Abstract

I didn’t find much about using the S81 in Linux, so I decided to test it myself, so far it works quite well.

About the Phone

The S81 is a rather cheap phone, I got one for Fr 100 (~60 €), paid another Fr 30 (~20 €) for a 2-GB micro-sd card. It works as a phone, and one can receive and send sms with it. It also works as mp3-player, camera (produces rather low-quality pictures, no comparison to my rather outdated Olympus UZ-700 digicam or even my Logitech Quickcam Fusion) and camcorder(really low resolution and not the best quality alltogether), emergency light, usb storage(only with micro-sd-card inserted, and only with cable always carried along, of course) and hopefully umts modem. One can greatly increase its usability by installing java programs, the most useful addition seemed to be a mobile bookreader, see below. The display is quite nice and well to read, but touch it and you’ll leave traces. So it’s perfect to take one’s fingerprints, but hard to keep it clean and shiny.