xenogenesi::blog
memento
3d adt android apache2 app apt aria2 build bullet cflags chromium codeigniter debian demoscene dependencies dpkg driver emulator freeglut gcc gfx git glut htaccess javascript json kernel linux make metalink minimal mysql opengl php python raspbian realtime rpi specs template toolchain update-alternatives video wifi wordpress
Dom, 15 Lug 2018 17:23:31 +0200

get ffmpeg sources and install build dependencies

mkdir ffmpeg-cuda
cd ffmpeg-cuda
apt-get source ffmpeg
sudo apt build-dep ffmpeg

patch the debian/rules to enable cuda (cuda dev packages need to be installed)

--- ffmpeg-3.4.2/debian/rules.orig      2018-03-18 00:08:00.717540941 +0100
+++ ffmpeg-3.4.2/debian/rules   2018-03-18 00:11:53.506937275 +0100
@@ -187,6 +187,8 @@
                --target-os=$(DEB_HOST_ARCH_OS)
 endif

+CONFIG += --enable-cuda --enable-cuvid --enable-nvenc --enable-nonfree --enable-libnpp --enable-cuda-sdk
+
 # Use the default debhelper scripts, where possible.
 %:
        dh $@

build it

cd ffmpeg-3.4.3
time nice dpkg-buildpackage -rfakeroot -uc -b -j5

the build will generate a bunch of *.deb files, they will conflict with the one installed by the system, so

mkdir install
for f in *.deb; do dpkg -x $f install; done

create a wrapper to use the built libraries (ffmpeg-cuda)

#!/bin/sh
export LD_LIBRARY_PATH=$INSTALL_PATH/usr/lib/x86_64-linux-gnu:$LD_LIBRARY_PATH
exec $INSTALL_PATH/usr/bin/ffmpeg "$@"

use it to encode, for instance

ffmpeg-cuda -hwaccel cuvid -c:v h264_cuvid -i "$1" -vf scale_npp=1280:720 -c:v h264_nvenc "$2"
ffmpeg-cuda -i "$1" -c:v h264_nvenc "$2"
Categories: debian · ffmpeg
Tags: · ·
Dom, 06 Mag 2018 21:16:07 +0200

If for some reason you’ve uninstalled the play store and you don’t trust third party mirrors, you can use the adb tool do download the apk from another phone.

Thanks to this SO answer: How do I get an apk file from an Android device?

adb shell pm path com.android.vending
adb pull /data/app/com.android.vending-2/base.apk  /tmp/com_android_vending-2-base.apk
Categories: android
Tags: · ·
Mer, 04 Apr 2018 14:19:07 +0200

by default debian/stretch apache2 installation have mod_rewrite disabled (at least the one used with debootstrap and lxc containers) so few steps are needed to enable it and .htaccess files

enable mod_rewrite (apache2 must be restarted, see below)

a2endmod rewrite

in the virtual host configuration enable .htaccess (apache2 must be restarted, see below)

<Directory "/var/www/htdocs">
     AllowOverride All
</Directory>

optionally enable mod_rewrite log (in the virtual host configuration) output goes into error.log (don’t leave it enabled in production) note: rewrite engine may need to be enabled before (apache2 must be restarted, see below)

RewriteEngine On
LogLevel alert rewrite:trace6

restart apache

systemctl restart apache2
Categories: debian · webdev
Tags: · · · ·
Sab, 13 Gen 2018 10:08:46 +0100

Assuming you’ve apache2 already installed and a reachable internet server running

apt-get install dehydrated

Add/edit /etc/apache2/conf-available/letscrypt.conf (notice the difference between the alias and the real directory which is plural acme-challenges):

Alias /.well-known/acme-challenge/ "/var/lib/dehydrated/acme-challenges/"
<Directory "/var/lib/dehydrated/acme-challenges/">
        Options None
        AllowOverride None
        # Apache 2.x
        <IfModule !mod_authz_core.c>
                Order allow,deny
                Allow from all
        </IfModule>
        # Apache 2.4
        <IfModule mod_authz_core.c>
                Require all granted
        </IfModule>
</Directory>

Add/edit /etc/dehydrated/conf.d/99_email.sh:

CONTACT_EMAIL="anymail@yourdomain"

Edit /etc/dehydrated/domains.txt, set the domains for which generate certificates.

Restart apache2 and run dehydrated -c, it should create the domain certs.

Edit your apache’s host file (/etc/apache2/sites-available/default-ssl.conf), replace DOMAIN with your domains:

SSLCertificateFile /var/lib/dehydrated/certs/DOMAIN/fullchain.pem
SSLCertificateKeyFile /var/lib/dehydrated/certs/DOMAIN/privkey.pem

Add/edit /etc/cron.daily/dehydrated:

#!/bin/sh

exec /usr/bin/dehydrated -c >/var/log/dehydrated-cron.log 2>&1

Run chmod 0755 /etc/cron.daily/dehydrated

Add/Edit /etc/logrotate.d/dehydrated:

/var/log/dehydrated-cron.log
{
        rotate 12
        monthly
        missingok
        notifempty
        delaycompress
        compress
}
Categories: debian · Senza categoria · webdev
Tags: · · · ·
Lun, 25 Dic 2017 17:22:12 +0100

Yii2’s guide about assets is good and explain how to compress, convert and combine bundles but lack some information, not every asset can be combined (for instance, javascripts with some custom dynamic module/plugins loading may cause some trouble).

The defaul hash() function:

$path = (is_file($path) ? dirname($path) : $path) . filemtime($path);
return sprintf('%x', crc32($path . Yii::getVersion() . '|' . $this->linkAssets));

it evaluates the directory full path and the file/directory mtime, Yii’s version and the option linkAssets, this mean if your development and production server have different paths the asset will need to be published again (as mentioned in the guide the option hashCallback could be used to modify this behavior).

You may want (as I do) to process your development environment to generate a production directory and publish all assets, even the one not combined, in the current Yii2 implementation there’s nothing ready to do so, you need to add a console command, something like that:

namespace app\commands;

use Yii;
use yii\console\Controller;

class PublishController extends Controller
{
    public function actionIndex($assetName = null) {

        Yii::setAlias('@webroot', __DIR__ . '/../web' );
        Yii::setAlias('@web', '/');

        if ($assetName != null) {
            echo "* publishing:  '$assetName'\n";
            $asset = new $assetName();
            $asset->publish(Yii::$app->assetManager);
            echo "  - sourcePath: $asset->sourcePath\n";
            echo "  - baseUrl: $asset->basePath\n";
        }
    }

then call it from the shell or a shell script (using the same namespace and class name used by Yii2’s loader to find the asset):

php yii publish noam148\\imagemanager\\assets\\ImageManagerAsset
Categories: webdev · yii2
Tags: ·
Ven, 04 Ago 2017 14:38:48 +0200

I needed a way to create many layers at once in inkscape, it support scripting with any language, the .inx file allow to define input parameters to insert with a GUI, they will be passed to the script as command line arguments

Place the .inx file and the python script in the inkscape directory

$HOME/.config/inkscape/extensions/create_layers.inx
$HOME/.config/inkscape/extensions/create_layers.py

create_layers.inx:

<?xml version="1.0" encoding="UTF-8"?>
<inkscape-extension xmlns="http://www.inkscape.org/namespace/inkscape/extension">
  <_name>Create Layers</_name>
  <id>org.xenogenesi.filter.create_layers</id>
  <dependency type="executable" location="extensions">create_layers.py</dependency>
  <dependency type="executable" location="extensions">inkex.py</dependency>
  <param name="basename" type="string" _gui-text="Base name of the new layer">New Layer {0}</param>
  <param name="count" type="string" _gui-text="Number of layers to create">10</param>
  <effect>
    <object-type>all</object-type>
    <effects-menu>
       <submenu _name="Layers"/>
    </effects-menu>
  </effect>
  <script>
    <command reldir="extensions" interpreter="python">create_layers.py</command>
  </script>
</inkscape-extension>

create_layers.py:

#!/usr/bin/env python

import inkex

class CreateLayersEffect(inkex.Effect):

    def __init__(self):

        inkex.Effect.__init__(self)

        self.OptionParser.add_option('-b', '--basename', action = 'store',
          type = 'string', dest = 'basename', default = 'New Layer {0}',
          help = 'Base name of the new layer')
        self.OptionParser.add_option('-c', '--count', action = 'store',
          type = 'string', dest = 'count', default = '10',
          help = 'Number of layers to create')

    def effect(self):
        basename = self.options.basename
        count = int(self.options.count)

        svg = self.document.getroot()

        for i in range(0, count):
            layer = inkex.etree.SubElement(svg, 'g')
            layer.set(inkex.addNS('label', 'inkscape'), basename.format(i))
            layer.set(inkex.addNS('groupmode', 'inkscape'), 'layer')

effect = CreateLayersEffect()
effect.affect()

github.com/xenogenesi/inkscape-pyext (one more extension to create layers for each selected object)

Here some great reference wiki.inkscape/Script_extensions

Categories: inkscape · python
Tags:
Mer, 02 Ago 2017 11:54:44 +0200

gimp support being scripted with python (2.7) menu Filters > Python Fu > console, you don’t even need to write a plugin, just type execfile("/some/path/your-script.py") to the console prompt

the python console have a very nice Browse button which allow to find the functions you need from the procedure browser (and their arguments), those may be exported from gimp or plugins

For example, I needed to crop each layer and save it as png file, save the name of the layer and the crop coordinates in a json file, here it is:

savepath="/tmp/slices/"
f=open("{0}images.json".format(savepath),"w")

print >> f, "["

def process_layer(image, layer):
    pdb.gimp_image_set_active_layer(image, layer)
    drawable = pdb.gimp_image_active_drawable(image)
    layer_name = pdb.gimp_item_get_name(drawable)
    if layer_name == "background":
        return

    pdb.gimp_selection_none(image)

    pdb.gimp_context_set_sample_merged(FALSE)
    pdb.gimp_context_set_antialias(FALSE)
    pdb.gimp_context_set_sample_transparent(TRUE)
    pdb.gimp_context_set_feather(FALSE)
    pdb.gimp_context_set_sample_threshold(0)
    pdb.gimp_image_select_contiguous_color(image, 2, drawable, 1, 1)
    pdb.gimp_selection_invert(image)
    non_empty, x1, y1, x2, y2 = pdb.gimp_selection_bounds(image)
    if non_empty:
        pdb.gimp_image_select_rectangle(image, 2, x1, y1, x2-x1, y2-y1)
        non_empty = pdb.gimp_edit_copy(drawable)
        if non_empty:
            image4 = pdb.gimp_edit_paste_as_new()
            active_layer = pdb.gimp_image_get_active_layer(image4)
            pdb.file_png_save2(image4, active_layer, "{0}{1}.png".format(savepath, layer_name), layer_name, TRUE, 9, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE)
            pdb.gimp_image_delete(image4)

            print >> f, "\t{{ \"{0}\": [ {1:d}, {2:d}, {3:d}, {4:d} ] }},".format(layer_name, x1, y1, x2, y2)
        else:
            print("gimp_edit_copy = empty ({0})".format(layer_name))
    else:
        print("gimp_selection_bounds = empty ({0})".format(layer_name))


image = gimp.image_list()[0]

for layer in image.layers:
    process_layer(image, layer)


print >> f, "]"

f.close()

github gist

Categories: gimp · python
Tags: ·
Lun, 31 Lug 2017 11:58:32 +0200

I’m using phing to automate a deploy of a php web application to production, phing is a really powerful tool (and easy to use), AdhocTaskdefTask allow to implement custom tags with input and output parameters, for example, I needed to adjust some relative path in production, there’s a simple adhoc task to get the new paths:

<!--
    Usage:
    <relative-path from="${from}" to="${to}"
        output="project_property" />
-->
<adhoc-task name="relative-path"><![CDATA[
    class RelativePath extends Task {
        private $from;
        private $to;
        private $output;

        function setFrom($from) {
            $this->from = $from;
        }

        function setTo($to) {
            $this->to = $to;
        }

        function setOutput($output=null) {
            $this->output = $output;
        }

        function main() {
            $relpath = $this->find_relative_path($this->from, $this->to);
            $this->log("relpath = " . $relpath);
            if ($this->output != null) {
                $this->project->setProperty($this->output, $relpath);
            }
        }

        /**
         * credits: https://gist.github.com/ohaal/2936041
         * Find the relative file system path between two file system paths
         *
         * @param  string  $frompath  Path to start from
         * @param  string  $topath    Path we want to end up in
         *
         * @return string             Path leading from $frompath to $topath
         */
        function find_relative_path ( $frompath, $topath ) {
            $from = explode( DIRECTORY_SEPARATOR, $frompath ); // Folders/File
            $to = explode( DIRECTORY_SEPARATOR, $topath ); // Folders/File
            $relpath = '';

            $i = 0;
            // Find how far the path is the same
            while ( isset($from[$i]) && isset($to[$i]) ) {
                if ( $from[$i] != $to[$i] ) break;
                $i++;
            }
            $j = count( $from ) - 1;
            // Add '..' until the path is the same
            while ( $i <= $j ) {
                if ( !empty($from[$j]) ) $relpath .= '..'.DIRECTORY_SEPARATOR;
                $j--;
            }
            // Go to folder from where it starts differing
            while ( isset($to[$i]) ) {
                if ( !empty($to[$i]) ) $relpath .= $to[$i].DIRECTORY_SEPARATOR;
                $i++;
            }

            // Strip last separator
            return substr($relpath, 0, -1);
        }
    }
]]></adhoc-task>
Categories: php · webdev
Tags: · ·
Dom, 16 Lug 2017 12:42:37 +0200

download the sources and build expdef.exe

  i686-w64-mingw32-g++-win32 -static -m32 -Wall -O2 -o expdef.exe expdef.cpp

generate the .def and the libsomething.dll.a implib

  wine ./expdef.exe -p -o something.dll >something.def
  i686-w64-mingw32-dlltool --no-leading-underscore -d something.def -D something.dll -l libsomething.dll.a

if something.dll use stdcall convention the sources need to prefix the prototype declarations with [[gnu::stdcal]]

  [[gnu::stdcall]] void *SomeFunctionInSomething(void);

build and link the executable

  i686-w64-mingw32-g++-win32 -Wall -O2 -I./include -o someprogram.exe someprogram.cpp -L. -lsomething

That’s it.

Categories: compiler
Tags: · · ·
Dom, 02 Lug 2017 11:54:15 +0200
mkdir ~/.git-templates

git config --global init.templatedir ~/.git-templates

git config -l

mkdir -p ~/.git-templates
tar -xvzf git-templates.tgz -C ~/.git-templates

get the url

cd ~/some-git-repo
git ls-remote --get-url 'origin'

EDIT ~/.gitconfig and add an entry

[user "url-from--get-url"]
    email = sample@eml
    name = name surname

check it is working

git clone <url-from--get-url> 

references: git-templates.tgz

Categories: git · Senza categoria
Tags: ·