[SOLVED] Seafile for Linux

Questions about WAPT Packaging / Requests and help regarding Wapt packages.
Forum Rules
Community Forum Rules
* English support on www.reddit.com/r/wapt
* French community support is available on this forum
* Please prefix the topic title with [RESOLVED] if it is resolved.
* Please do not edit a topic that is tagged [RESOLVED]. Open a new topic referencing the old one.
* Specify the installed WAPT version, full version, and build number (2.2.1.11957 / 2.2.2.12337 / etc.) as well as the Enterprise/Discovery edition.
* Versions 1.8.2 and earlier are no longer supported. The only questions accepted regarding version 1.8.2 are related to upgrading to a supported version (2.1, 2.2, etc.).
* Specify the server OS (Linux/Windows) and version (Debian Buster/Bullseye - CentOS 7 - Windows Server 2012/2016/2019).
* Specify the OS of the administration/package creation machine and the machine with the problematic agent, if applicable (Windows 7/10/11/Debian 11/etc.).
* Avoid asking multiple questions when opening a topic, otherwise it may be ignored. If there are multiple topics, open separate topics, preferably one after the other and not all at the same time (i.e., do not spam the forum).
* Include code snippets, screenshots, and other images directly in the post. Links to Pastebin, Bitly, and other third-party sites will be systematically removed.
* As with any community forum, support is provided voluntarily by members. If you require commercial support, you can contact Tranquil IT's sales department at 02.40.97.57.55
Locked
jmorillo
Messages: 7
Registration: Oct 16, 2024 - 3:26 p.m.

December 2, 2025 - 4:15 PM

Hello everyone!

Seafile, since version 9.0.7, no longer provides .deb packages on their repository. Therefore, the latest version on their repository (and thus on Wapt) is 9.0.6.
They have now switched to the AppImage format. :(
I quickly cobbled together a working package based on what already existed, so I'm sharing the code with you.

control piqued on the windows version:

Code: Select all

package           : tis-seafile
version           : 9.0.15-0
architecture      : x64
section           : base
priority          : optional
name              : Seafile
categories        : Office
maintainer        : WAPT Team,Tranquil IT,Jimmy PELÉ,Hubert TOUVET,Amelie LE JEUNE
description       : Seafile is an open source file storage and sharing solution
depends           : 
conflicts         : 
maturity          : DEV
locale            : all
target_os         : linux
min_wapt_version  : 2.3
sources           : https://www.seafile.com/en/download/
installed_size    : 282629518
impacted_process  :
description_fr    : Seafile est une solution de stockage et de partage de fichiers open source
description_pl    : Seafile to rozwiązanie open source do przechowywania i udostępniania plików
description_de    : Seafile ist eine Open-Source-Lösung zur Speicherung und gemeinsamen Nutzung von Dateien
description_es    : Seafile es una solución de código abierto para almacenar y compartir archivos
description_pt    : O Seafile é uma solução de armazenamento e partilha de ficheiros de código aberto
description_it    : Seafile è una soluzione open source per l'archiviazione e la condivisione di file
description_nl    : Seafile is een open source oplossing voor het opslaan en delen van bestanden
description_ru    : Seafile - это решение для хранения и обмена файлами с открытым исходным кодом
audit_schedule    : 
editor            : HaiWenHuZhi ltd.
keywords          : seafile,cloud,file,storage,sharing,solution,client
licence           : opensource_free,wapt_public,cpe:/a:gnu:gpl_v2
homepage          : https://www.seafile.com/
setup.py is taken from authme, which knows how to handle appimages

Code: Select all

# -*- coding: utf-8 -*-
from setuphelpers import *
from iniparse import ConfigParser
import os


def install():
    # Custom --------------------------
    # Uninstall old Seafile app (.deb)
    appname = control.package.split('-',1)[1]
    for to_uninstall in installed_softwares(name=appname):
        print('Remove package: %s' % to_uninstall["name"])
        uninstall_apt(to_uninstall["name"])    
    if isfile('/etc/apt/sources.list.d/%s.sources' % appname):
        print('Remove %s.sources' % appname)
        remove_file('/etc/apt/sources.list.d/%s.sources' % appname)
    if isfile('/etc/apt/sources.list.d/%s.list' % appname):
        print('Remove %s.list' % appname)
        remove_file('/etc/apt/sources.list.d/%s.list' % appname)

    # libfuse2 needed to play with appimage
    if (get_distrib_linux() == "ubuntu" and Version(get_distrib_version(), 1) >= "24") or (get_distrib_linux() == "debian" and Version(get_distrib_version(), 1) >= "13"):
        install_apt('libfuse2t64')
    else:
        install_apt('libfuse2')

    # set a symlink to avoid ugly warning at start
    if isfile('/usr/lib/x86_64-linux-gnu/libwayland-client.so.0'):
        print('Found libwayland')
        if not isfile('/usr/lib64/libwayland-client.so.0'):
            print('Symlink to libwayland not present, creating symlink')
            os.symlink('/usr/lib/x86_64-linux-gnu/libwayland-client.so.0', '/usr/lib64/libwayland-client.so.0')
    # Custom ------------------------------
    
    install_dir = makepath('/','opt',control.package.split('-',1)[1])
    appimage = glob.glob("*.AppImage")[0]
    install_appimage(appimage,install_dir)

def uninstall():
    install_dir = makepath('/','opt',control.package.split('-',1)[1])
    uninstall_appimage(install_dir)

def install_appimage(appimage,install_dir,binaliasname=None):
    run('chmod a+x ./' + appimage)

    if isdir(install_dir):
        uninstall_appimage(install_dir)

    mkdirs(install_dir)

    name_appimage = appimage.split('/')[-1]
    filecopyto(appimage, makepath(install_dir, name_appimage))
    run('"./%s" --appimage-extract' % appimage)
    

    for desktop in glob.glob(makepath('squashfs-root','*.desktop')):
 
        desktop_cp = ConfigParser()
        desktop_cp.optionxform = str
        desktop_file = open(desktop, encoding="utf-8")
        desktop_cp.readfp(desktop_file)
        bin_path = desktop_cp.get('Desktop Entry',"Exec")

        newbin_path = install_dir + '/' + name_appimage
        if ' %' in bin_path:
            newbin_path = newbin_path + ' %' + bin_path.split(' %',1)[1]

        icon_path = desktop_cp.get('Desktop Entry',"Icon")

        srcicon = makepath('squashfs-root',icon_path +'.svg')
        if not isfile(srcicon):
            srcicon = makepath('squashfs-root',icon_path +'.png')
        new_icon = install_dir + '/' + srcicon.split('/')[-1]
        filecopyto(srcicon,new_icon)

        desktop_cp.set('Desktop Entry',"Exec",newbin_path)
        desktop_cp.set('Desktop Entry',"Icon",new_icon)
        desktop_cp.remove_option('Desktop Entry', 'TryExec') # Default TryExec is misformated, remove it
        desktop_cp.set('Desktop Entry',"TryExec",install_dir + '/' + name_appimage) # Create new TryExec entry
        with open(desktop, 'w', encoding="utf-8") as f:
            desktop_cp.write(f)

        pathdesk = makepath(install_dir,desktop.split('/')[-1])
        filecopyto(desktop, pathdesk)
        run('chown root:root "%s" ' % pathdesk)

    for f in glob.glob(makepath(install_dir,'*.desktop')):
        run('ln -sf "%s" "/usr/share/applications/%s"' % (f,f.split('/')[-1]))
        run('update-desktop-database /usr/share/applications/') # Update launcher

    if binaliasname :
        run(f"ln -sf {install_dir}/{name_appimage} /usr/bin/{binaliasname}")

    remove_tree('squashfs-root')

def uninstall_appimage(install_dir):

    if not glob.glob(makepath(install_dir,'*.desktop')):
        error('.desktop not found')

    for f in glob.glob(makepath(install_dir,'*.desktop')):
        deskfile = f.split('/')[-1]
        system_desktop = makepath("/","usr","share","applications",deskfile)
        if isfile(system_desktop):
            remove_file(system_desktop)
    remove_tree(install_dir)

# Add application Daemon to autostart applications
def session_setup():
    appname = control.package.split('-',1)[1]
    if isfile(makepath("/","home",get_current_user(),".config","autostart","%s.desktop" % appname)):
        print("Autostart already exist")
    else:
        print("Set autostart for user %s" % get_current_user())
        filecopyto(makepath("/","opt","%s","%s.desktop") % (appname,appname), makepath("/","home",get_current_user(),".config","autostart","%s.desktop" % appname))
Finally, the update_package.py file was taken from Windows' Seafile and very slightly modified.

Code: Select all

# -*- coding: utf-8 -*-
from setuphelpers import *
from setupdevhelpers import *


def update_package():
    # Declaring local variables
    package_updated = False
    proxies = get_proxies()
    if not proxies:
        proxies = get_proxies_from_wapt_console()
    url = "https://www.seafile.com/en/download/"

    # Getting latest version from official sources
    print("URL used is: %s" % url)
    bs_search = bs_find_all(url, "a", "class", "download-op")[2] # custom
    version = bs_search.text
    download_url = bs_search["href"]
    latest_bin = download_url.split("/")[-1]

    # Downloading latest binaries
    print("Latest %s version is: %s" % (control.name, version))
    print("Download URL is: %s" % download_url)
    if not isfile(latest_bin):
        print("Downloading: %s" % latest_bin)
        wget(download_url, latest_bin, proxies=proxies)
        run('chmod +x %s' % latest_bin)
    else:
        print("Binary is present: %s" % latest_bin)

    # Deleting outdated binaries
    remove_outdated_binaries(latest_bin)
    # arch_list = ensure_list(control.architecture)
    # remove_outdated_binaries(version, filename_contains=("x64" if "x64" in arch_list else "x86" if "x86" in arch_list else []))

    # Checking version from file
    if get_os_name() == "Windows" and "windows" in control.target_os.lower():
        version_from_file = get_version_from_binary(latest_bin)
        if Version(version_from_file, 4) == Version(version, 4):
            print(f"INFO: Binary file version ({version_from_file}) corresponds to online version ({version})")
        else:
            error(f"ERROR: Binary file version ({version_from_file}) do NOT corresponds to online version ({version})")

    # Changing version of the package
    if Version(version, 4) > Version(control.get_software_version(), 4):
        print("Software version updated (from: %s to: %s)" % (control.get_software_version(), Version(version)))
        package_updated = True
    else:
        print("Software version up-to-date (%s)" % Version(version))
    control.set_software_version(version)
    control.save_control_to_wapt()

    # Validating or not update-package-sources
    return package_updated

    # # Changing version of the package and validating update-package-sources
    # return complete_control_version(control, version)
Have a good day everyone
gadam
Messages: 23
Registration: Oct 30, 2025 - 2:46 p.m.

December 9, 2025 - 3:54 PM

Hello,

Thank you for your post. We have modified the Seafile package for Linux. Its release to the production store is scheduled for December 14th at 2 PM. In the meantime, the package is available in pre-production here: https://wapt.tranquil.it/store/fr/detai ... EPROD.wapt

Have a good day!
Gwenaël
Locked