Skip to content

Commit

Permalink
Separate command-line binary (#120)
Browse files Browse the repository at this point in the history
* initial draft of separate cli application

* reorganize main.cpp in cli a bit, towards real commands parser impl (still wip)

* parsing command line arguments in new CLI

* console obj with quiet logic extracted; config checking in CLI implemented

* move QNapi class to libqnapi; implementing subtitles downloading in CLI (wip)

* more informative error formatting

* ported CLI functionality to a separated binary

* updating translations for new CLI (wip)

* improving translation

* err codes as constants, not magic numbers; more rational downloading loop break

* qmake option to disable building cli/gui targets

* install mediainfo (to be present in pkgconfig) for macx cli build

* hide ssl warnings from printing to console

* fix asking for input in quiet mode

* win32 deploy commands supporting both qnapic.exe/qnapi.exe

* updated input for doxygen doc (added cli sources)

* install pkgconfig for brew

* add no_cli/no_gui note to README.md

* not install pkgconfig for brew (seems to be already present)

* fix pkgconfig issue on macx

* get rid of cat

* further refactoring

* implementing gui command parser (wip), improving cli command parser

* abstractios CliArgParser/CliArgParsersExecutor prototyped

* QNapiCommand + ShowHelpArgParser

* ShowHelpLanguages arg parser

* QuietBatch arg parser

* ShowList / DontShowList arg parsers

* fixed parsers executor

* lang arg parser

* backup lang arg parser

* format arg parser

* extension arg parser

* download subtitles arg parser

* bug fixes in arg parsers

* replace old cli arg parsers with new design in CLI

* show options args parser, run cli app args parser

* use parsers in GUI; wip

* scan directory arg parser

* improved error message about CLI binary not found

* removed QNapiCli from gui app

* replace close button & manual alignment with dialog button box (frmAbout)

* Console extracted to libqnapi / utils

* formatting arg switches help based on cli arg data (wip, cleanup needed)

* renaming

* removed obsolete CLI help text

* translations updated

* fixed tr functions to show valid help text translations

* display gui help in dialog

* show gui help about -c, small code cleanup

* code cleanup

* extracting help text producing logic to libqnapi

* translations updated

* init napisy24SubMenu in constructor

* memory release

* removed qt@5.7 on osx

* fix .travis.yml formatting

* added NsProcess.zip binary

* add qt 5.9 and 5.10.0 on appveyor

* add help languages msgbox with translation

* use Qt 5.6.3 instead of 5.6.2 on Travis

* add linux qt 5.10.1 build on travis

* 10.8 mac minimal version
  • Loading branch information
krzemin authored Mar 8, 2018
1 parent 391880f commit c9a6cd6
Show file tree
Hide file tree
Showing 78 changed files with 3,483 additions and 1,512 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ debug
release
Makefile*
qnapi
qnapic
*.a
win32/out/*
win32/*.exe
Expand Down
17 changes: 10 additions & 7 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -52,15 +52,17 @@ matrix:
compiler: gcc
env:
- QT_BASE=59
- os: linux
dist: trusty
sudo: required
compiler: gcc
env:
- QT_BASE=510
- os: osx
compiler: clang
env:
- QT_BASE=55
- MAKE_DMG=1
- os: osx
compiler: clang
env:
- QT_BASE=57
- os: osx
compiler: clang
env:
Expand All @@ -76,8 +78,8 @@ before_install:
- if [[ "$QT_BASE" = "57" && "$TRAVIS_OS_NAME" = "linux" ]]; then sudo add-apt-repository ppa:beineri/opt-qt571-trusty -y; fi
- if [[ "$QT_BASE" = "58" && "$TRAVIS_OS_NAME" = "linux" ]]; then sudo add-apt-repository ppa:beineri/opt-qt58-trusty -y; fi
- if [[ "$QT_BASE" = "59" && "$TRAVIS_OS_NAME" = "linux" ]]; then sudo add-apt-repository ppa:beineri/opt-qt593-trusty -y; fi
- if [[ "$QT_BASE" = "510" && "$TRAVIS_OS_NAME" = "linux" ]]; then sudo add-apt-repository ppa:beineri/opt-qt510-trusty -y; fi
- if [ "$TRAVIS_OS_NAME" = "linux" ]; then
- if [[ "$QT_BASE" = "510" && "$TRAVIS_OS_NAME" = "linux" ]]; then sudo add-apt-repository ppa:beineri/opt-qt-5.10.1-trusty -y; fi
- if [ "$TRAVIS_OS_NAME" = "linux" ]; then
sudo apt-get update -qq;
else
brew update;
Expand All @@ -87,6 +89,7 @@ before_install:

install:
- if [ "$TRAVIS_OS_NAME" = "linux" ]; then sudo apt-get install -qq libmediainfo-dev; fi
- if [ "$TRAVIS_OS_NAME" = "osx" ]; then brew install mediainfo; fi
- if [ "$TRAVIS_OS_NAME" = "osx" ]; then npm install -g appdmg; fi
- if [[ "$QT_BASE" = "51" && "$TRAVIS_OS_NAME" = "linux" ]]; then sudo apt-get install -qq qt51base; source /opt/qt51/bin/qt51-env.sh; fi
- if [[ "$QT_BASE" = "52" && "$TRAVIS_OS_NAME" = "linux" ]]; then sudo apt-get install -qq qt52base; source /opt/qt52/bin/qt52-env.sh; fi
Expand All @@ -97,8 +100,8 @@ install:
- if [[ "$QT_BASE" = "57" && "$TRAVIS_OS_NAME" = "linux" ]]; then sudo apt-get install -qq qt57base; source /opt/qt57/bin/qt57-env.sh; fi
- if [[ "$QT_BASE" = "58" && "$TRAVIS_OS_NAME" = "linux" ]]; then sudo apt-get install -qq qt58base; source /opt/qt58/bin/qt58-env.sh; fi
- if [[ "$QT_BASE" = "59" && "$TRAVIS_OS_NAME" = "linux" ]]; then sudo apt-get install -qq qt59base; source /opt/qt59/bin/qt59-env.sh; fi
- if [[ "$QT_BASE" = "510" && "$TRAVIS_OS_NAME" = "linux" ]]; then sudo apt-get install -qq qt510base; source /opt/qt510/bin/qt510-env.sh; fi
- if [[ "$QT_BASE" = "55" && "$TRAVIS_OS_NAME" = "osx" ]]; then brew install qt@5.5; brew link --force qt@5.5; fi
- if [[ "$QT_BASE" = "57" && "$TRAVIS_OS_NAME" = "osx" ]]; then brew install qt@5.7; brew link --force qt@5.7; fi
- if [[ "$QT_BASE" = "510" && "$TRAVIS_OS_NAME" = "osx" ]]; then brew install qt; brew link --force qt; fi


Expand Down
1 change: 1 addition & 0 deletions Doxyfile
Original file line number Diff line number Diff line change
Expand Up @@ -791,6 +791,7 @@ WARN_LOGFILE =
# Note: If this tag is empty the current directory is searched.

INPUT = gui/src \
cli/src \
libqnapi/src

# This tag can be used to specify the character encoding of the source files
Expand Down
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@ To compile the application, you have to execute two following commands in `qnapi

This will produce `Makefile`.

> By appending `CONFIG+=no_cli` or `CONFIG+=no_gui` to qmake invocation you can disable building
> command-line or graphical interface binaries.

`$ make` (or `mingw32-make` on Windows)

This will compile the sources and build executable binary (or app bundle on OSX).
Expand Down
11 changes: 8 additions & 3 deletions appveyor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,12 @@ environment:
MINGW: C:\Qt\Tools\mingw530_32
DEPLOY: 0
- QT5: C:\Qt\5.8\mingw53_32
MINGW: C:\Qt\Tools\mingw530_32
DEPLOY: 0
- QT5: C:\Qt\5.9\mingw53_32
MINGW: C:\Qt\Tools\mingw530_32
DEPLOY: 0
- QT5: C:\Qt\5.10.0\mingw53_32
MINGW: C:\Qt\Tools\mingw530_32
DEPLOY: 1

Expand All @@ -22,9 +28,8 @@ matrix:
install:
- appveyor-retry cinst nsis -y -version 2.51
- appveyor-retry cinst 7zip.commandline -y -x86
- appveyor DownloadFile "http://nsis.sourceforge.net/mediawiki/images/archive/1/18/20140806212030!NsProcess.zip" -FileName NsProcess.zip
- 7z e -o"C:\Program Files (x86)\NSIS\Include" NsProcess.zip Include\*.nsh
- 7z e -o"C:\Program Files (x86)\NSIS\Plugins" NsProcess.zip Plugin\*.dll
- 7z e -o"C:\Program Files (x86)\NSIS\Include" deps\ns-process\NsProcess.zip Include\*.nsh
- 7z e -o"C:\Program Files (x86)\NSIS\Plugins" deps\ns-process\NsProcess.zip Plugin\*.dll
- git submodule update --init --recursive

before_build:
Expand Down
47 changes: 47 additions & 0 deletions cli/cli.pro
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
TEMPLATE = app

CONFIG += warn_on qt resources silent c++11 console

QT += core network xml
QT -= gui

SOURCES += src/main.cpp \
src/clisubtitlesdownloader.cpp \
src/climain.cpp

HEADERS += \
src/clisubtitlesdownloader.h \
src/climain.h

RESOURCES += res/resources.qrc

MOC_DIR = tmp
RCC_DIR = tmp
OBJECTS_DIR = tmp
INCLUDEPATH = src

include(../libqnapi/libqnapi.pri)

unix {
TARGET = qnapic
DESTDIR = ../
CONFIG += link_pkgconfig
PKGCONFIG += libmediainfo
}

macx {
QT_CONFIG -= no-pkg-config
CONFIG -= app_bundle
LIBS += -framework CoreFoundation
QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.8
QMAKE_CXXFLAGS_X86_64 = -mmacosx-version-min=10.8
}

win32 {
CONFIG += nostrip
RC_FILE = ../win32/qnapi.rc
TARGET = qnapic
target.path = ../win32/out
INSTALLS += target
}

6 changes: 6 additions & 0 deletions cli/res/resources.qrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<RCC>
<qresource prefix="/translations">
<file alias="qnapi_it.qm">../../translations/qnapi_it.qm</file>
<file alias="qnapi_pl.qm">../../translations/qnapi_pl.qm</file>
</qresource>
</RCC>
140 changes: 140 additions & 0 deletions cli/src/climain.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
/*****************************************************************************
** QNapi
** Copyright (C) 2008-2017 Piotr Krzemiński <pio.krzeminski@gmail.com>
**
** 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 2 of the License, or
** (at your option) any later version.
**
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
**
*****************************************************************************/

#include "climain.h"
#include "clisubtitlesdownloader.h"
#include "libqnapi.h"
#include "qnapicommand.h"
#include "subtitlelanguage.h"
#include "utils/helphelper.h"

#include <signal.h>
#include <QDir>
#include <QTranslator>
#include <iostream>

namespace CliMain {

void installTranslation(QCoreApplication &app, QTranslator *translator,
const QNapiConfig &config) {
QString uiLanguage = LibQNapi::uiLanguage(config.generalConfig());
translator->load("qnapi_" + uiLanguage, ":/translations");
app.installTranslator(translator);
}

void printHeader(const Console &c) {
c.printLine(tr("QNapi %1 (Qt version %2), %3")
.arg(LibQNapi::displayableVersion())
.arg(qVersion())
.arg(LibQNapi::webpageUrl()));
c.printLine();
}

void printHelp(const Console &c,
const QList<QSharedPointer<CliArgParser>> &cliArgParsers) {
auto helpLines = HelpHelper::formatHelpLinesText(cliArgParsers);
foreach (auto helpLine, helpLines) { c.printLine(helpLine); }
}

void printHelpLanguages(const Console &c, const QNapiConfig &config) {
c.printLine(
tr("List of languages recognized by QNapi, including corresponding"));
c.printLine(tr("two-letter language codes:"));
c.printLine();

SubtitleLanguage L, LB;
QStringList langs = L.listLanguages();

foreach (QString lang, langs) {
L.setLanguage(lang);
c.printLine(QString(" %1 - %2").arg(L.toTwoLetter()).arg(lang));
}

L.setLanguage(config.generalConfig().language());
LB.setLanguage(config.generalConfig().backupLanguage());

c.printLine();
c.printLine(tr("Current default subtitles language: %1 (%2)")
.arg(L.toFullName())
.arg(L.toTwoLetter()));

if (LB.toFullName().isEmpty()) {
c.printLine(tr("No alternative subtitles language has been set"));
} else {
c.printLine(tr("Current alternative subtitles language: %1 (%2)")
.arg(LB.toFullName())
.arg(LB.toTwoLetter()));
}
}

int processCommand(QVariant cliCommand, const QNapiConfig &config,
const QList<QSharedPointer<CliArgParser>> &cliArgParsers) {
const Console c(config.generalConfig().quietBatch());

printHeader(c);

using namespace QNapiCommand;
if (cliCommand.canConvert<DownloadSubtitles>()) {
QStringList movieFilePaths =
cliCommand.value<DownloadSubtitles>().movieFilePaths;
return CliSubtitlesDownloader::downloadSubtitlesFor(c, movieFilePaths,
config);
} else if (cliCommand.canConvert<ShowHelpLanguages>()) {
printHelpLanguages(c, config);
return 0;
} else {
printHelp(c, cliArgParsers);
return 0;
}
}

void sigHandler(int sig) {
Q_UNUSED(sig);

std::cout << std::endl
<< tr("QNapi: deleting temporary files...").toStdString()
<< std::endl;

const QNapiConfig config = LibQNapi::loadConfig();
QString tmpPath = config.generalConfig().tmpPath();
QDir tmpDir(tmpPath);

QStringList filters;
filters << "QNapi-*-rc";
filters << "QNapi.*.tmp";

QFileInfoList files = tmpDir.entryInfoList(filters);

foreach (QFileInfo file, files) { QFile::remove(file.filePath()); }

std::cout << tr("QNapi: finished.").toStdString() << std::endl;

exit(666);
}

void regSignal() {
#ifdef Q_OS_WIN
signal(SIGTERM, sigHandler);
signal(SIGINT, sigHandler);
#else
struct sigaction sa;
memset(&sa, 0, sizeof(struct sigaction));
sigemptyset(&sa.sa_mask);
sa.sa_handler = sigHandler;
sigaction(SIGTERM, &sa, 0);
sigaction(SIGINT, &sa, 0);
#endif
}

} // namespace CliMain
41 changes: 41 additions & 0 deletions cli/src/climain.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*****************************************************************************
** QNapi
** Copyright (C) 2008-2017 Piotr Krzemiński <pio.krzeminski@gmail.com>
**
** 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 2 of the License, or
** (at your option) any later version.
**
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
**
*****************************************************************************/

#ifndef CLIMAIN_H
#define CLIMAIN_H

#include "config/qnapiconfig.h"
#include "parser/cliargparser.h"
#include "parser/cliargparsersexecutor.h"
#include "tr.h"
#include "utils/console.h"

namespace CliMain {

Q_DECLARE_NAMESPACE_TR(CliMain)

void installTranslation(QCoreApplication &app, QTranslator *translator,
const QNapiConfig &config);
void printHeader(const Console &c);
void printHelp(const Console &c,
const QList<QSharedPointer<CliArgParser>> &cliArgParsers);
void printHelpLanguages(const Console &c, const QNapiConfig &config);
int processCommand(QVariant cliCommand, const QNapiConfig &config,
const QList<QSharedPointer<CliArgParser>> &cliArgParsers);
void sigHandler(int sig);
void regSignal();

} // namespace CliMain

#endif // CLIMAIN_H
Loading

0 comments on commit c9a6cd6

Please sign in to comment.