StreamLabels en Arch Linux
  • Miércoles 9 de Diciembre de 2020

StreamLabels en Arch Linux

Hace un tiempo hablamos de   StreamLabs y de como este nos puede servir para realizar streamings en GNU/Linux. También hablamos de su herramienta Stream Labels la cual tiene como disponible un .deb para que lo utilicemos en linux. Lamentablemente los .deb solo funcionan en distribuciones basadas en Debian/Ubuntu y eso no suele ser compatible con todos los que intentamos realizar Streaming dado que los que jugamos sabemos que el mejor rendimiento está en Arch Linux.

Una explicación no basta

Si bien en aquel   artículo explique cómo debería realizarse la conversión para utilizarlo en Arch no creo que todo el mundo tenga que ponerse a ver estas cosas. Por lo cual decidí subirlo a AUR para que todo aquel que desee utilizarlo pueda hacerlo sin ningún problema. por lo cual, a partir de hoy si queremos utilizarlo basta con un solo comando para utilizarlo.

1
yay -S streamlabels

¿Cómo funciona AUR?¿Es difícil subir mi paquete?

Realmente es muy sencillo, aunque vale aclarar que puede costar identificar bien en un inicio como hacerlo correctamente. Por lo cual a modo de muestra en esta oportunidad voy a dejar como está construido este repositorio de Stream Labels para que logren imaginarse como es. Todo el proceso del registro en AUR y demás confío en que pueden…

PKGBUILD

Esta es la magia de AUR, con este archivo basta para subir un repo que esté disponible para todo el mundo. En este archivo vamos a encontrar, las sumas md5 de todos los archivos utilizados, el nombre del paquete, la versión, la descarga, el proceso de instalación, dependencias, descripción, etc…

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
# Maintainer: Joaquin (Pato) Decima <https://patojad.com.ar/>

pkgname=streamlabels
pkgver=0.3.8
pkgrel=2
pkgdesc="Stream Labels is an application that runs on your computer that generates text files. These text files contain stats, including your top donor for the day, your most recent follower, and many others."
arch=('x86_64')
url="https://patojad.com.ar/aplicaciones/2020/12/streamlabels-en-arch-linux/"
license=('GPL')
source=("https://s3-us-west-2.amazonaws.com/streamlabs-electron/streamlabels_0.3.8_amd64.deb"
        "pjadalien.py")
md5sums=('ade077aa9baf135de156b169d8d4ecd8'
         '8b65bd2668e7b7acc0768e16841130bc')


package() {
    cd $_pkgbase
    python $srcdir/pjadalien.py $srcdir/streamlabels_0.3.8_amd64.deb
    sudo pacman -U $srcdir/streamlabels-0.3.8-1-x86_64.pkg.tar.gz
}

Como podemos ver este archivo usa 2 source, una que lo descarga desde la url y otro que se encuentra el en mismo repositorio, en este caso es un pjadalien.py que es nada más ni nada menos que archalien con una modificación para poder funcionar correctamente con el .deb que estamos utilizando.

  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
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
from __future__ import print_function
from __future__ import division
from __future__ import absolute_import
import sys
import os
from shutil import rmtree
from tempfile import mkdtemp
from getopt import gnu_getopt, GetoptError

pkgrel=1

def command_required(*cmd_list):
    """Check if the commands exist."""
    path = os.getenv('PATH')
    if path is not None:
        path_list = path.split(os.pathsep)
    else:
        print("The environment variable PATH is not defined.")
        sys.exit(1)

    for command in cmd_list:
        error = True

        for path in path_list:
            command_path = os.path.join(path, command)
            if os.access(command_path, os.X_OK):
                error = False
                break

        if error:
            print('The command \'%s\' is not found.' % command)
            sys.exit(1)


def fix_input_pkg(input_pkg):
    """Verify and fix the input package path.

    It returns the input package, modified.

    """
    if not os.path.isfile(input_pkg):
        print('\'%s\' doesn\'t exist.' % input_pkg)
        sys.exit(1)

    if not os.access(input_pkg, os.R_OK):
        print('\'%s\' is not accessible in reading.' % input_pkg)

    (_, input_ext) = os.path.splitext(input_pkg)

    if input_ext != '.deb':
        print('The extension of \'%s\' must be *.deb.' % input_pkg)
        sys.exit(1)

    # Convert to the absolute path
    input_pkg = os.path.abspath(input_pkg)

    return input_pkg


def usage():
    """Called when the user uses --help."""
    print('Convert a Debian or an RPM Package into an Arch Linux package'
          ' (and vice-versa).')
    print()
    print('Usage: %s [OPTIONS] debian_package.deb [arch_package.pkg.tar.gz]'
          % os.path.basename(sys.argv[0]))
    print()
    print("OPTIONS :")
    print("          -h, --help            Show this help")
    print()
    sys.exit(0)


def more_informations():
    """Asks the user to use --help."""
    print("--help for more informations.")
    sys.exit(1)


def handle_arguments():
    """Handle all options in the arguments.

    This function returns a dictionary that contain
    'input_pkg' and 'output_pkg' keywords.

    """
    result = {'input_pkg': '', 'output_pkg': ''}

    try:
        args = sys.argv[1:]
        optlist = gnu_getopt(args, 'h', ['help'])
    except GetoptError:
        print('Error when parsing arguments.')
        more_informations()

    if len(sys.argv) < 2:
        print('No input file.')
        more_informations()

    for option, _ in optlist[0]:
        if option in ['-h', '--help']:
            usage()

    result['input_pkg'] = optlist[1][0]

    if len(sys.argv) > 3:
        result['output_pkg'] = optlist[1][1]

    return result


def read_debcontrol(path):
    """Read some informations from debian/control."""
    result = {'name': '', 'maintainer': '', 'version': '',
              'description': '', 'size': '', 'architecture': ''}

    try:
        filedesc = open(path, 'r')
    except IOError:
        print('Cannot read debian package informations from \'%s\'.' % path)
        sys.exit(1)

    for line in filedesc.readlines():
        line = line.rstrip('\n')
        try:
            (variable, value) = [splited.strip().lower()
                                 for splited in line.split(':', 1)]
        except ValueError:
            continue

        if variable == 'package':
            result['name'] = value
        if variable == 'installed-size':
            result['size'] = value
        if variable == 'version':
            try:
                before, after = value.split(':')
            except ValueError:
                result[variable] = value
            else:
                result[variable] = after

            result[variable] = result[variable].replace('-', '_')
        elif variable in ['maintainer', 'version', 'description']:
            result[variable] = value
        elif variable == 'architecture':
            if value == 'amd64':
                result['architecture'] = 'x86_64'
            elif value == 'i386':
                result['architecture'] = 'i686'  # on Arch Linux, i686 only
            elif value == 'i686':
                result['architecture'] = 'i686'
            else:
                result['architecture'] = 'all'

    filedesc.close()

    for key, value in list(result.items()):
        if value == '' and key not in ['size']:
            print('The debian package doesn\'t '
                  'contain all needed informations.\n'
                  'The variable \'%s\' is empty.' % key)
            ##sys.exit(1)

    return result


def write_archcontrol(path, pkginfo):
    """Write an Arch Linux PKGINFO in 'path'.

    'pkginfo' is a dictionary that contain some informations
    returned by read_debcontrol().

    """
    try:
        filedesc = open(path, 'w')
    except IOError:
        print('\'%s\' is not accessible in writing.' % path)
        sys.exit(1)

    filedesc.write('# Generated by Alien Arch\n')
    filedesc.write('pkgname = %s\n' % pkginfo['name'])
    filedesc.write('pkgver = %s-%s\n' % (pkginfo['version'], pkgrel))
    filedesc.write('pkgdesc = %s\n' % pkginfo['description'])
    filedesc.write('packager = Arch Linux, Alien Arch '
                   '(http://www.archlinux.org)\n')
    filedesc.write('size = %s\n' % pkginfo['size'])
    filedesc.write('arch = %s\n' % pkginfo['architecture'])
    filedesc.write('license =\n')
    # filedesc.write('url =\n')
    # filedesc.write('builddate =\n')
    # filedesc.write('depend =\n')

    filedesc.close()


def convert(input_pkg, output_pkg=''):
    """Convert a Debian package to an Arch Linux package.

    input_pkg contains the input package, with *.deb extension.

    output_pkg contains the output package, with *.pkg.tar.gz extension. This
    argument is not obligatory.

    """
    (input_tmpd, output_tmpd) = (mkdtemp(), mkdtemp())

    input_pkg = fix_input_pkg(input_pkg)
    print('Conversion of %s...' % os.path.basename(input_pkg))
    print()

    def chdir(directory):
        """Change the directory."""
        try:
            os.chdir(directory)
        except OSError:
            print('Cannot chdir to %s.' % directory)
            sys.exit(1)

    try:
        chdir(input_tmpd)

        # Extraction of the deb archive
        os.system('ar x \'%s\'' % input_pkg)

        if os.path.exists('data.tar.gz'):
            data_path = 'data.tar.gz'
        else:
            for found_data_path in os.listdir('.'):
                if found_data_path.find('data.tar') == 0:
                    data_path = found_data_path
                    break

            if data_path == '':
                print("The data archive wasn't found inside %s" % input_pkg)
                sys.exit(1)

        # Extraction of control.tar.gz and data.tar.x
        os.system('tar xf \'%s\' -C \'%s\'' %
                  (os.path.join(input_tmpd, data_path),
                   output_tmpd))
        os.system('tar xf \'%s\'' %
                  (os.path.join(input_tmpd, 'control.tar.gz')))

        # Reading 'control' file, from the deb archive
        deb_info = read_debcontrol(os.path.join(input_tmpd, 'control'))

        # If the output filename is not specified, it will be created
        if output_pkg == '':
            output_pkg = os.path.join(os.path.dirname(input_pkg),
                                      '%s-%s-%s-%s''.pkg.tar.gz'
                                      % (deb_info['name'], deb_info['version'],
                                         pkgrel, deb_info['architecture']))

        # Creating Arch Linux package
        chdir(output_tmpd)
        os.system('find . -type f | sed -e \'s/^\\.\\///\' > .FILELIST')
        write_archcontrol('.PKGINFO', deb_info)
        os.system('tar zcf \'%s\' * .PKGINFO .FILELIST' % output_pkg)

        print("done.")
        print()
        print('The Arch Linux package:\n%s' % output_pkg)
    finally:
        rmtree(input_tmpd, True)
        rmtree(output_tmpd, True)


if __name__ == '__main__':
    try:
        command_required('ar', 'tar', 'find', 'sed')
        DATA = handle_arguments()
        convert(DATA['input_pkg'],
                DATA['output_pkg'])
    except KeyboardInterrupt:
        print("Interrupted.")

# vim:ai:et:sw=4:ts=4:sts=4:tw=78:fenc=utf-8

.SRCINFO

Este es un archivo que si lo olvidamos solo trae problemas por lo cual yo tengo como regla personal siempre antes de hacer un commit a un repositorio AUR ejecutar este pequeño comando que se encarga nada más ni nada menos de actualizar este archivo el cual es necesario para que el commit sea aceptado.

1
makepkg --printsrcinfo > .SRCINFO

Contenido Relacionado

PatoJAD

PatoJAD

Arquitecto de Software

Autor

Sobre mi no hay mucho para decir, me dedico a desarrollar en una empresa de telecomunicaciones, utilizo GNU/Linux desde el 2.012 y hace años que es mi Sistema Operativo main. Soy una persona que busca crecer profesionalmente sin dejar de divertirse y hacer lo que me gusta. Siempre digo que cuando un proyecto sale es importante agradecer, por lo cual les recomiendo a todos leer la seccion Agradecimientos en la cual me tomé un tiempito para poder agradecer a todos y cada uno de los que hicieron posible todo esto.