Upgraded code to switch to C++17. Tested on Debian Buster

This commit is contained in:
emeric
2019-09-10 13:07:06 +02:00
parent 178c400067
commit 2c5917235a
82 changed files with 723 additions and 755 deletions
+157 -159
View File
@@ -1,8 +1,8 @@
Installation Instructions
*************************
Copyright (C) 1994-1996, 1999-2002, 2004-2013 Free Software Foundation,
Inc.
Copyright (C) 1994-1996, 1999-2002, 2004-2016 Free Software
Foundation, Inc.
Copying and distribution of this file, with or without modification,
are permitted in any medium without royalty provided the copyright
@@ -12,97 +12,96 @@ without warranty of any kind.
Basic Installation
==================
Briefly, the shell command `./configure && make && make install'
Briefly, the shell command './configure && make && make install'
should configure, build, and install this package. The following
more-detailed instructions are generic; see the `README' file for
more-detailed instructions are generic; see the 'README' file for
instructions specific to this package. Some packages provide this
`INSTALL' file but do not implement all of the features documented
'INSTALL' file but do not implement all of the features documented
below. The lack of an optional feature in a given package is not
necessarily a bug. More recommendations for GNU packages can be found
in *note Makefile Conventions: (standards)Makefile Conventions.
The `configure' shell script attempts to guess correct values for
The 'configure' shell script attempts to guess correct values for
various system-dependent variables used during compilation. It uses
those values to create a `Makefile' in each directory of the package.
It may also create one or more `.h' files containing system-dependent
definitions. Finally, it creates a shell script `config.status' that
those values to create a 'Makefile' in each directory of the package.
It may also create one or more '.h' files containing system-dependent
definitions. Finally, it creates a shell script 'config.status' that
you can run in the future to recreate the current configuration, and a
file `config.log' containing compiler output (useful mainly for
debugging `configure').
file 'config.log' containing compiler output (useful mainly for
debugging 'configure').
It can also use an optional file (typically called `config.cache'
and enabled with `--cache-file=config.cache' or simply `-C') that saves
the results of its tests to speed up reconfiguring. Caching is
disabled by default to prevent problems with accidental use of stale
cache files.
It can also use an optional file (typically called 'config.cache' and
enabled with '--cache-file=config.cache' or simply '-C') that saves the
results of its tests to speed up reconfiguring. Caching is disabled by
default to prevent problems with accidental use of stale cache files.
If you need to do unusual things to compile the package, please try
to figure out how `configure' could check whether to do them, and mail
diffs or instructions to the address given in the `README' so they can
to figure out how 'configure' could check whether to do them, and mail
diffs or instructions to the address given in the 'README' so they can
be considered for the next release. If you are using the cache, and at
some point `config.cache' contains results you don't want to keep, you
some point 'config.cache' contains results you don't want to keep, you
may remove or edit it.
The file `configure.ac' (or `configure.in') is used to create
`configure' by a program called `autoconf'. You need `configure.ac' if
you want to change it or regenerate `configure' using a newer version
of `autoconf'.
The file 'configure.ac' (or 'configure.in') is used to create
'configure' by a program called 'autoconf'. You need 'configure.ac' if
you want to change it or regenerate 'configure' using a newer version of
'autoconf'.
The simplest way to compile this package is:
1. `cd' to the directory containing the package's source code and type
`./configure' to configure the package for your system.
1. 'cd' to the directory containing the package's source code and type
'./configure' to configure the package for your system.
Running `configure' might take a while. While running, it prints
Running 'configure' might take a while. While running, it prints
some messages telling which features it is checking for.
2. Type `make' to compile the package.
2. Type 'make' to compile the package.
3. Optionally, type `make check' to run any self-tests that come with
3. Optionally, type 'make check' to run any self-tests that come with
the package, generally using the just-built uninstalled binaries.
4. Type `make install' to install the programs and any data files and
4. Type 'make install' to install the programs and any data files and
documentation. When installing into a prefix owned by root, it is
recommended that the package be configured and built as a regular
user, and only the `make install' phase executed with root
user, and only the 'make install' phase executed with root
privileges.
5. Optionally, type `make installcheck' to repeat any self-tests, but
5. Optionally, type 'make installcheck' to repeat any self-tests, but
this time using the binaries in their final installed location.
This target does not install anything. Running this target as a
regular user, particularly if the prior `make install' required
regular user, particularly if the prior 'make install' required
root privileges, verifies that the installation completed
correctly.
6. You can remove the program binaries and object files from the
source code directory by typing `make clean'. To also remove the
files that `configure' created (so you can compile the package for
a different kind of computer), type `make distclean'. There is
also a `make maintainer-clean' target, but that is intended mainly
source code directory by typing 'make clean'. To also remove the
files that 'configure' created (so you can compile the package for
a different kind of computer), type 'make distclean'. There is
also a 'make maintainer-clean' target, but that is intended mainly
for the package's developers. If you use it, you may have to get
all sorts of other programs in order to regenerate files that came
with the distribution.
7. Often, you can also type `make uninstall' to remove the installed
7. Often, you can also type 'make uninstall' to remove the installed
files again. In practice, not all packages have tested that
uninstallation works correctly, even though it is required by the
GNU Coding Standards.
8. Some packages, particularly those that use Automake, provide `make
8. Some packages, particularly those that use Automake, provide 'make
distcheck', which can by used by developers to test that all other
targets like `make install' and `make uninstall' work correctly.
targets like 'make install' and 'make uninstall' work correctly.
This target is generally not run by end users.
Compilers and Options
=====================
Some systems require unusual options for compilation or linking that
the `configure' script does not know about. Run `./configure --help'
the 'configure' script does not know about. Run './configure --help'
for details on some of the pertinent environment variables.
You can give `configure' initial values for configuration parameters
by setting variables in the command line or in the environment. Here
is an example:
You can give 'configure' initial values for configuration parameters
by setting variables in the command line or in the environment. Here is
an example:
./configure CC=c99 CFLAGS=-g LIBS=-lposix
@@ -113,21 +112,21 @@ Compiling For Multiple Architectures
You can compile the package for more than one kind of computer at the
same time, by placing the object files for each architecture in their
own directory. To do this, you can use GNU `make'. `cd' to the
own directory. To do this, you can use GNU 'make'. 'cd' to the
directory where you want the object files and executables to go and run
the `configure' script. `configure' automatically checks for the
source code in the directory that `configure' is in and in `..'. This
is known as a "VPATH" build.
the 'configure' script. 'configure' automatically checks for the source
code in the directory that 'configure' is in and in '..'. This is known
as a "VPATH" build.
With a non-GNU `make', it is safer to compile the package for one
With a non-GNU 'make', it is safer to compile the package for one
architecture at a time in the source code directory. After you have
installed the package for one architecture, use `make distclean' before
installed the package for one architecture, use 'make distclean' before
reconfiguring for another architecture.
On MacOS X 10.5 and later systems, you can create libraries and
executables that work on multiple system types--known as "fat" or
"universal" binaries--by specifying multiple `-arch' options to the
compiler but only a single `-arch' option to the preprocessor. Like
"universal" binaries--by specifying multiple '-arch' options to the
compiler but only a single '-arch' option to the preprocessor. Like
this:
./configure CC="gcc -arch i386 -arch x86_64 -arch ppc -arch ppc64" \
@@ -136,105 +135,104 @@ this:
This is not guaranteed to produce working output in all cases, you
may have to build one architecture at a time and combine the results
using the `lipo' tool if you have problems.
using the 'lipo' tool if you have problems.
Installation Names
==================
By default, `make install' installs the package's commands under
`/usr/local/bin', include files under `/usr/local/include', etc. You
can specify an installation prefix other than `/usr/local' by giving
`configure' the option `--prefix=PREFIX', where PREFIX must be an
By default, 'make install' installs the package's commands under
'/usr/local/bin', include files under '/usr/local/include', etc. You
can specify an installation prefix other than '/usr/local' by giving
'configure' the option '--prefix=PREFIX', where PREFIX must be an
absolute file name.
You can specify separate installation prefixes for
architecture-specific files and architecture-independent files. If you
pass the option `--exec-prefix=PREFIX' to `configure', the package uses
pass the option '--exec-prefix=PREFIX' to 'configure', the package uses
PREFIX as the prefix for installing programs and libraries.
Documentation and other data files still use the regular prefix.
In addition, if you use an unusual directory layout you can give
options like `--bindir=DIR' to specify different values for particular
kinds of files. Run `configure --help' for a list of the directories
you can set and what kinds of files go in them. In general, the
default for these options is expressed in terms of `${prefix}', so that
specifying just `--prefix' will affect all of the other directory
options like '--bindir=DIR' to specify different values for particular
kinds of files. Run 'configure --help' for a list of the directories
you can set and what kinds of files go in them. In general, the default
for these options is expressed in terms of '${prefix}', so that
specifying just '--prefix' will affect all of the other directory
specifications that were not explicitly provided.
The most portable way to affect installation locations is to pass the
correct locations to `configure'; however, many packages provide one or
correct locations to 'configure'; however, many packages provide one or
both of the following shortcuts of passing variable assignments to the
`make install' command line to change installation locations without
'make install' command line to change installation locations without
having to reconfigure or recompile.
The first method involves providing an override variable for each
affected directory. For example, `make install
affected directory. For example, 'make install
prefix=/alternate/directory' will choose an alternate location for all
directory configuration variables that were expressed in terms of
`${prefix}'. Any directories that were specified during `configure',
but not in terms of `${prefix}', must each be overridden at install
time for the entire installation to be relocated. The approach of
makefile variable overrides for each directory variable is required by
the GNU Coding Standards, and ideally causes no recompilation.
However, some platforms have known limitations with the semantics of
shared libraries that end up requiring recompilation when using this
method, particularly noticeable in packages that use GNU Libtool.
'${prefix}'. Any directories that were specified during 'configure',
but not in terms of '${prefix}', must each be overridden at install time
for the entire installation to be relocated. The approach of makefile
variable overrides for each directory variable is required by the GNU
Coding Standards, and ideally causes no recompilation. However, some
platforms have known limitations with the semantics of shared libraries
that end up requiring recompilation when using this method, particularly
noticeable in packages that use GNU Libtool.
The second method involves providing the `DESTDIR' variable. For
example, `make install DESTDIR=/alternate/directory' will prepend
`/alternate/directory' before all installation names. The approach of
`DESTDIR' overrides is not required by the GNU Coding Standards, and
The second method involves providing the 'DESTDIR' variable. For
example, 'make install DESTDIR=/alternate/directory' will prepend
'/alternate/directory' before all installation names. The approach of
'DESTDIR' overrides is not required by the GNU Coding Standards, and
does not work on platforms that have drive letters. On the other hand,
it does better at avoiding recompilation issues, and works well even
when some directory options were not specified in terms of `${prefix}'
at `configure' time.
when some directory options were not specified in terms of '${prefix}'
at 'configure' time.
Optional Features
=================
If the package supports it, you can cause programs to be installed
with an extra prefix or suffix on their names by giving `configure' the
option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
with an extra prefix or suffix on their names by giving 'configure' the
option '--program-prefix=PREFIX' or '--program-suffix=SUFFIX'.
Some packages pay attention to `--enable-FEATURE' options to
`configure', where FEATURE indicates an optional part of the package.
They may also pay attention to `--with-PACKAGE' options, where PACKAGE
is something like `gnu-as' or `x' (for the X Window System). The
`README' should mention any `--enable-' and `--with-' options that the
Some packages pay attention to '--enable-FEATURE' options to
'configure', where FEATURE indicates an optional part of the package.
They may also pay attention to '--with-PACKAGE' options, where PACKAGE
is something like 'gnu-as' or 'x' (for the X Window System). The
'README' should mention any '--enable-' and '--with-' options that the
package recognizes.
For packages that use the X Window System, `configure' can usually
For packages that use the X Window System, 'configure' can usually
find the X include and library files automatically, but if it doesn't,
you can use the `configure' options `--x-includes=DIR' and
`--x-libraries=DIR' to specify their locations.
you can use the 'configure' options '--x-includes=DIR' and
'--x-libraries=DIR' to specify their locations.
Some packages offer the ability to configure how verbose the
execution of `make' will be. For these packages, running `./configure
execution of 'make' will be. For these packages, running './configure
--enable-silent-rules' sets the default to minimal output, which can be
overridden with `make V=1'; while running `./configure
overridden with 'make V=1'; while running './configure
--disable-silent-rules' sets the default to verbose, which can be
overridden with `make V=0'.
overridden with 'make V=0'.
Particular systems
==================
On HP-UX, the default C compiler is not ANSI C compatible. If GNU
CC is not installed, it is recommended to use the following options in
On HP-UX, the default C compiler is not ANSI C compatible. If GNU CC
is not installed, it is recommended to use the following options in
order to use an ANSI C compiler:
./configure CC="cc -Ae -D_XOPEN_SOURCE=500"
and if that doesn't work, install pre-built binaries of GCC for HP-UX.
HP-UX `make' updates targets which have the same time stamps as
their prerequisites, which makes it generally unusable when shipped
generated files such as `configure' are involved. Use GNU `make'
instead.
HP-UX 'make' updates targets which have the same time stamps as their
prerequisites, which makes it generally unusable when shipped generated
files such as 'configure' are involved. Use GNU 'make' instead.
On OSF/1 a.k.a. Tru64, some versions of the default C compiler cannot
parse its `<wchar.h>' header file. The option `-nodtk' can be used as
a workaround. If GNU CC is not installed, it is therefore recommended
to try
parse its '<wchar.h>' header file. The option '-nodtk' can be used as a
workaround. If GNU CC is not installed, it is therefore recommended to
try
./configure CC="cc"
@@ -242,26 +240,26 @@ and if that doesn't work, try
./configure CC="cc -nodtk"
On Solaris, don't put `/usr/ucb' early in your `PATH'. This
On Solaris, don't put '/usr/ucb' early in your 'PATH'. This
directory contains several dysfunctional programs; working variants of
these programs are available in `/usr/bin'. So, if you need `/usr/ucb'
in your `PATH', put it _after_ `/usr/bin'.
these programs are available in '/usr/bin'. So, if you need '/usr/ucb'
in your 'PATH', put it _after_ '/usr/bin'.
On Haiku, software installed for all users goes in `/boot/common',
not `/usr/local'. It is recommended to use the following options:
On Haiku, software installed for all users goes in '/boot/common',
not '/usr/local'. It is recommended to use the following options:
./configure --prefix=/boot/common
Specifying the System Type
==========================
There may be some features `configure' cannot figure out
There may be some features 'configure' cannot figure out
automatically, but needs to determine by the type of machine the package
will run on. Usually, assuming the package is built to be run on the
_same_ architectures, `configure' can figure that out, but if it prints
_same_ architectures, 'configure' can figure that out, but if it prints
a message saying it cannot guess the machine type, give it the
`--build=TYPE' option. TYPE can either be a short name for the system
type, such as `sun4', or a canonical name which has the form:
'--build=TYPE' option. TYPE can either be a short name for the system
type, such as 'sun4', or a canonical name which has the form:
CPU-COMPANY-SYSTEM
@@ -270,101 +268,101 @@ where SYSTEM can have one of these forms:
OS
KERNEL-OS
See the file `config.sub' for the possible values of each field. If
`config.sub' isn't included in this package, then this package doesn't
See the file 'config.sub' for the possible values of each field. If
'config.sub' isn't included in this package, then this package doesn't
need to know the machine type.
If you are _building_ compiler tools for cross-compiling, you should
use the option `--target=TYPE' to select the type of system they will
use the option '--target=TYPE' to select the type of system they will
produce code for.
If you want to _use_ a cross compiler, that generates code for a
platform different from the build platform, you should specify the
"host" platform (i.e., that on which the generated programs will
eventually be run) with `--host=TYPE'.
eventually be run) with '--host=TYPE'.
Sharing Defaults
================
If you want to set default values for `configure' scripts to share,
you can create a site shell script called `config.site' that gives
default values for variables like `CC', `cache_file', and `prefix'.
`configure' looks for `PREFIX/share/config.site' if it exists, then
`PREFIX/etc/config.site' if it exists. Or, you can set the
`CONFIG_SITE' environment variable to the location of the site script.
A warning: not all `configure' scripts look for a site script.
If you want to set default values for 'configure' scripts to share,
you can create a site shell script called 'config.site' that gives
default values for variables like 'CC', 'cache_file', and 'prefix'.
'configure' looks for 'PREFIX/share/config.site' if it exists, then
'PREFIX/etc/config.site' if it exists. Or, you can set the
'CONFIG_SITE' environment variable to the location of the site script.
A warning: not all 'configure' scripts look for a site script.
Defining Variables
==================
Variables not defined in a site shell script can be set in the
environment passed to `configure'. However, some packages may run
environment passed to 'configure'. However, some packages may run
configure again during the build, and the customized values of these
variables may be lost. In order to avoid this problem, you should set
them in the `configure' command line, using `VAR=value'. For example:
them in the 'configure' command line, using 'VAR=value'. For example:
./configure CC=/usr/local2/bin/gcc
causes the specified `gcc' to be used as the C compiler (unless it is
causes the specified 'gcc' to be used as the C compiler (unless it is
overridden in the site shell script).
Unfortunately, this technique does not work for `CONFIG_SHELL' due to
an Autoconf limitation. Until the limitation is lifted, you can use
this workaround:
Unfortunately, this technique does not work for 'CONFIG_SHELL' due to an
Autoconf limitation. Until the limitation is lifted, you can use this
workaround:
CONFIG_SHELL=/bin/bash ./configure CONFIG_SHELL=/bin/bash
`configure' Invocation
'configure' Invocation
======================
`configure' recognizes the following options to control how it
'configure' recognizes the following options to control how it
operates.
`--help'
`-h'
Print a summary of all of the options to `configure', and exit.
'--help'
'-h'
Print a summary of all of the options to 'configure', and exit.
`--help=short'
`--help=recursive'
'--help=short'
'--help=recursive'
Print a summary of the options unique to this package's
`configure', and exit. The `short' variant lists options used
only in the top level, while the `recursive' variant lists options
also present in any nested packages.
'configure', and exit. The 'short' variant lists options used only
in the top level, while the 'recursive' variant lists options also
present in any nested packages.
`--version'
`-V'
Print the version of Autoconf used to generate the `configure'
'--version'
'-V'
Print the version of Autoconf used to generate the 'configure'
script, and exit.
`--cache-file=FILE'
'--cache-file=FILE'
Enable the cache: use and save the results of the tests in FILE,
traditionally `config.cache'. FILE defaults to `/dev/null' to
traditionally 'config.cache'. FILE defaults to '/dev/null' to
disable caching.
`--config-cache'
`-C'
Alias for `--cache-file=config.cache'.
'--config-cache'
'-C'
Alias for '--cache-file=config.cache'.
`--quiet'
`--silent'
`-q'
'--quiet'
'--silent'
'-q'
Do not print messages saying which checks are being made. To
suppress all normal output, redirect it to `/dev/null' (any error
suppress all normal output, redirect it to '/dev/null' (any error
messages will still be shown).
`--srcdir=DIR'
'--srcdir=DIR'
Look for the package's source code in directory DIR. Usually
`configure' can determine that directory automatically.
'configure' can determine that directory automatically.
`--prefix=DIR'
Use DIR as the installation prefix. *note Installation Names::
for more details, including other options available for fine-tuning
the installation locations.
'--prefix=DIR'
Use DIR as the installation prefix. *note Installation Names:: for
more details, including other options available for fine-tuning the
installation locations.
`--no-create'
`-n'
'--no-create'
'-n'
Run the configure checks, but stop before creating any output
files.
`configure' also accepts some other, not widely useful, options. Run
`configure --help' for more details.
'configure' also accepts some other, not widely useful, options. Run
'configure --help' for more details.
+3 -1
View File
@@ -48,9 +48,11 @@ __Note__: since _LMS_ stores hashed and salted passwords, it cannot handle the _
## Installation
__Note__: this installation process and the default values of the configuration file and the _systemd_ service file have been written for _Debian Stretch_. Therefore, you may have to adapt commands and/or paths in order to fit to your distribution.
__Note__: this installation process and the default values of the configuration file and the _systemd_ service file have been written for _Debian Buster_. Therefore, you may have to adapt commands and/or paths in order to fit to your distribution.
### Build dependencies
__Note__: a C++17 compiler is needed to compile _LMS_
```sh
apt-get install g++ autoconf automake libboost-filesystem-dev libboost-system-dev libavcodec-dev libavutil-dev libavformat-dev libav-tools libmagick++-dev libpstreams-dev libconfig++-dev libpstreams-dev ffmpeg libtag1-dev
```
+9 -10
View File
@@ -5,7 +5,6 @@ AC_CONFIG_HEADER(src/config/config.h)
AC_LANG_CPLUSPLUS
# Checks for programs
AC_PROG_CXX
PKG_CHECK_MODULES(IMAGEMAGICKXX, "ImageMagick++", [ HAVE_IMAGEMAGICKXX=yes ], [ ])
@@ -20,10 +19,15 @@ AC_CHECK_HEADERS([Wt/WApplication.h pstreams/pstream.h],
[],
[AC_MSG_ERROR([Header not found or unusable !])])
AC_CHECK_LIB( [pthread],
[pthread_rwlock_unlock],
,
[AC_MSG_ERROR([libpthread not found!])])
AC_CHECK_LIB([stdc++fs],
[main],
,
[AC_MSG_ERROR([lib filesystem not found!])])
AC_CHECK_LIB([pthread],
[pthread_rwlock_unlock],
,
[AC_MSG_ERROR([libpthread not found!])])
AC_CHECK_LIB([wt],
[main],
@@ -66,11 +70,6 @@ AC_CHECK_LIB([boost_system],
,
[AC_MSG_ERROR([libboost_system not found!])])
AC_CHECK_LIB( [boost_filesystem],
[main],
,
[AC_MSG_ERROR([libboost_filesystem not found!])])
AC_CHECK_LIB( [tag],
[main],
,
+3 -3
View File
@@ -25,8 +25,8 @@ lms_SOURCES = \
$(srcdir)/database/Artist.hpp \
$(srcdir)/database/Cluster.cpp \
$(srcdir)/database/Cluster.hpp \
$(srcdir)/database/Database.cpp \
$(srcdir)/database/Database.hpp \
$(srcdir)/database/Db.cpp \
$(srcdir)/database/Db.hpp \
$(srcdir)/database/TrackArtistLink.cpp \
$(srcdir)/database/TrackArtistLink.hpp \
$(srcdir)/database/TrackFeatures.cpp \
@@ -147,6 +147,6 @@ lms_SOURCES = \
$(srcdir)/utils/Utils.cpp \
$(srcdir)/utils/Utils.hpp
lms_CXXFLAGS=-std=c++14 -Wall -I$(srcdir)/ui $(MAGICKXX_CFLAGS) -D_REENTRANT
lms_CXXFLAGS=-std=c++17 -I$(srcdir)/ui $(MAGICKXX_CFLAGS) -D_REENTRANT
lms_LDADD=$(MAGICKXX_LIBS)
+4 -4
View File
@@ -27,7 +27,7 @@
namespace API::Subsonic
{
boost::optional<Id>
std::optional<Id>
IdFromString(const std::string& id)
{
if (id == "root")
@@ -35,7 +35,7 @@ IdFromString(const std::string& id)
std::vector<std::string> values {splitString(id, "-")};
if (values.size() != 2)
return boost::none;
return std::nullopt;
Id res;
@@ -49,11 +49,11 @@ IdFromString(const std::string& id)
else if (type == "pl")
res.type = Id::Type::Playlist;
else
return boost::none;
return std::nullopt;
auto optId {readAs<Database::IdType>(values[1])};
if (!optId)
return boost::none;
return std::nullopt;
res.value = *optId;
+2 -2
View File
@@ -17,7 +17,7 @@
* along with LMS. If not, see <http://www.gnu.org/licenses/>.
*/
#include <boost/optional.hpp>
#include <optional>
#include "database/Types.hpp"
@@ -39,7 +39,7 @@ struct Id
Database::IdType value {};
};
boost::optional<Id> IdFromString(const std::string& id);
std::optional<Id> IdFromString(const std::string& id);
std::string IdToString(const Id& id);
} // namespace API::Subsonic
+38 -37
View File
@@ -31,6 +31,7 @@
#include "cover/CoverArtGrabber.hpp"
#include "database/Artist.hpp"
#include "database/Cluster.hpp"
#include "database/Db.hpp"
#include "database/Release.hpp"
#include "database/Track.hpp"
#include "database/TrackList.hpp"
@@ -53,14 +54,14 @@ static const Av::Encoding transcodeEncoding {Av::Encoding::MP3};
static const std::string reportedStarredDate {"2000-01-01T00:00:00"};
template<>
boost::optional<API::Subsonic::Id>
std::optional<API::Subsonic::Id>
readAs(const std::string& str)
{
return API::Subsonic::IdFromString(str);
}
template<>
boost::optional<bool>
std::optional<bool>
readAs(const std::string& str)
{
if (str == "true")
@@ -82,31 +83,31 @@ struct ClientVersion
}
template<>
boost::optional<API::Subsonic::ClientVersion>
std::optional<API::Subsonic::ClientVersion>
readAs(const std::string& str)
{
// Expects "X.Y.Z"
const auto numbers {splitString(str, ".")};
if (numbers.size() < 2 || numbers.size() > 3)
return boost::none;
return std::nullopt;
API::Subsonic::ClientVersion version;
auto number {readAs<unsigned>(numbers[0])};
if (!number)
return boost::none;
return std::nullopt;
version.major = *number;
number = {readAs<unsigned>(numbers[1])};
if (!number)
return boost::none;
return std::nullopt;
version.minor = *number;
if (numbers.size() == 3)
{
number = {readAs<unsigned>(numbers[2])};
if (!number)
return boost::none;
return std::nullopt;
version.patch = *number;
}
@@ -132,12 +133,12 @@ struct RequestContext
std::string userName;
};
using SessionMap = std::map<Database::Database*, std::unique_ptr<Session>>;
using SessionMap = std::map<Db*, std::unique_ptr<Session>>;
static std::map<std::thread::id, SessionMap> dbSessions;
static
Session&
getOrCreateDbSession(Database::Database& db)
getOrCreateDbSession(Db& db)
{
static std::mutex mutex;
@@ -152,12 +153,12 @@ getOrCreateDbSession(Database::Database& db)
if (it != std::end(*sessionMap))
return *it->second;
auto res {sessionMap->emplace(&db, db.createSession())};
auto res { sessionMap->try_emplace(&db, db.createSession())};
assert(res.second);
LMS_LOG(API_SUBSONIC, DEBUG) << "Created db session";
return *(res.first->second);
return *res.first->second;
}
static
@@ -209,7 +210,7 @@ getMandatoryMultiParametersAs(const Wt::Http::ParameterMap& parameterMap, const
}
template<typename T>
boost::optional<T>
std::optional<T>
getParameterAs(const Wt::Http::ParameterMap& parameterMap, const std::string& param)
{
std::vector<T> params {getMultiParametersAs<T>(parameterMap, param)};
@@ -277,7 +278,7 @@ struct MediaRetrievalResult
Wt::cpp17::any continuationData;
};
SubsonicResource::SubsonicResource(Database::Database& db)
SubsonicResource::SubsonicResource(Db& db)
: _db {db}
{
}
@@ -571,7 +572,7 @@ userToResponseNode(const User::pointer& user)
static
Response
handlePingRequest(RequestContext& context)
handlePingRequest(RequestContext&)
{
return Response::createOkResponse();
}
@@ -731,12 +732,12 @@ handleDeleteUserRequest(RequestContext& context)
static
Response
handleGetLicenseRequest(RequestContext& context)
handleGetLicenseRequest(RequestContext&)
{
Response response {Response::createOkResponse()};
Response::Node& licenseNode {response.createNode("license")};
licenseNode.setAttribute("licenseExpires", "2019-09-03T14:46:43");
licenseNode.setAttribute("licenseExpires", "2025-09-03T14:46:43");
licenseNode.setAttribute("email", "foo@bar.com");
licenseNode.setAttribute("valid", "true");
@@ -748,7 +749,7 @@ Response
handleGetRandomSongsRequest(RequestContext& context)
{
// Optional params
std::size_t size {getParameterAs<std::size_t>(context.parameters, "size").get_value_or(50)};
std::size_t size {getParameterAs<std::size_t>(context.parameters, "size").value_or(50)};
size = std::min(size, std::size_t {500});
auto transaction {context.dbSession.createSharedTransaction()};
@@ -776,8 +777,8 @@ handleGetAlbumListRequestCommon(const RequestContext& context, bool id3)
std::string type {getMandatoryParameterAs<std::string>(context.parameters, "type")};
// Optional params
std::size_t size {getParameterAs<std::size_t>(context.parameters, "size").get_value_or(10)};
std::size_t offset {getParameterAs<std::size_t>(context.parameters, "offset").get_value_or(0)};
std::size_t size {getParameterAs<std::size_t>(context.parameters, "size").value_or(10)};
std::size_t offset {getParameterAs<std::size_t>(context.parameters, "offset").value_or(0)};
std::vector<Release::pointer> releases;
@@ -932,7 +933,7 @@ handleGetArtistInfoRequestCommon(RequestContext& context, bool id3)
throw BadParameterGenericError {"id"};
// Optional params
std::size_t count {getParameterAs<std::size_t>(context.parameters, "count").get_value_or(20)};
std::size_t count {getParameterAs<std::size_t>(context.parameters, "count").value_or(20)};
Response response {Response::createOkResponse()};
Response::Node& artistInfoNode {response.createNode(id3 ? "artistInfo2" : "artistInfo")};
@@ -1075,7 +1076,7 @@ handleGetMusicDirectoryRequest(RequestContext& context)
static
Response
handleGetMusicFoldersRequest(RequestContext& context)
handleGetMusicFoldersRequest(RequestContext&)
{
Response response {Response::createOkResponse()};
Response::Node& musicFoldersNode {response.createNode("musicFolders")};
@@ -1142,7 +1143,7 @@ handleGetSimilarSongsRequestCommon(RequestContext& context, bool id3)
throw BadParameterGenericError {"id"};
// Optional params
std::size_t count {getParameterAs<std::size_t>(context.parameters, "count").get_value_or(50)};
std::size_t count {getParameterAs<std::size_t>(context.parameters, "count").value_or(50)};
auto similarArtistsId {getService<Similarity::Searcher>()->getSimilarArtists(context.dbSession, id.value, 5)};
@@ -1248,7 +1249,7 @@ handleGetStarred2Request(RequestContext& context)
static
Response::Node
tracklistToResponseNode(const TrackList::pointer& tracklist, Session& dbSession)
tracklistToResponseNode(const TrackList::pointer& tracklist, Session&)
{
Response::Node playlistNode;
@@ -1322,10 +1323,10 @@ handleGetSongsByGenreRequest(RequestContext& context)
std::string genre {getMandatoryParameterAs<std::string>(context.parameters, "genre")};
// Optional params
std::size_t size {getParameterAs<std::size_t>(context.parameters, "count").get_value_or(10)};
std::size_t size {getParameterAs<std::size_t>(context.parameters, "count").value_or(10)};
size = std::min(size, std::size_t {500});
std::size_t offset {getParameterAs<std::size_t>(context.parameters, "offset").get_value_or(0)};
std::size_t offset {getParameterAs<std::size_t>(context.parameters, "offset").value_or(0)};
auto transaction {context.dbSession.createSharedTransaction()};
@@ -1398,12 +1399,12 @@ handleSearchRequestCommon(RequestContext& context, bool id3)
std::vector<std::string> keywords {splitString(query, " ")};
// Optional params
std::size_t artistCount {getParameterAs<std::size_t>(context.parameters, "artistCount").get_value_or(20)};
std::size_t artistOffset {getParameterAs<std::size_t>(context.parameters, "artistOffset").get_value_or(0)};
std::size_t albumCount {getParameterAs<std::size_t>(context.parameters, "albumCount").get_value_or(20)};
std::size_t albumOffset {getParameterAs<std::size_t>(context.parameters, "albumOffset").get_value_or(0)};
std::size_t songCount {getParameterAs<std::size_t>(context.parameters, "songCount").get_value_or(20)};
std::size_t songOffset {getParameterAs<std::size_t>(context.parameters, "songOffset").get_value_or(0)};
std::size_t artistCount {getParameterAs<std::size_t>(context.parameters, "artistCount").value_or(20)};
std::size_t artistOffset {getParameterAs<std::size_t>(context.parameters, "artistOffset").value_or(0)};
std::size_t albumCount {getParameterAs<std::size_t>(context.parameters, "albumCount").value_or(20)};
std::size_t albumOffset {getParameterAs<std::size_t>(context.parameters, "albumOffset").value_or(0)};
std::size_t songCount {getParameterAs<std::size_t>(context.parameters, "songCount").value_or(20)};
std::size_t songOffset {getParameterAs<std::size_t>(context.parameters, "songOffset").value_or(0)};
auto transaction {context.dbSession.createSharedTransaction()};
@@ -1585,8 +1586,8 @@ Response
handleUpdateUserRequest(RequestContext& context)
{
std::string username {getMandatoryParameterAs<std::string>(context.parameters, "username")};
boost::optional<std::string> password {getParameterAs<std::string>(context.parameters, "password")};
boost::optional<Bitrate> maxBitRate {getParameterAs<Bitrate>(context.parameters, "maxBitRate")};
std::optional<std::string> password {getParameterAs<std::string>(context.parameters, "password")};
std::optional<Bitrate> maxBitRate {getParameterAs<Bitrate>(context.parameters, "maxBitRate")};
User::PasswordHash hash;
if (password)
@@ -1693,9 +1694,9 @@ createTranscoder(RequestContext& context)
Id id {getMandatoryParameterAs<Id>(context.parameters, "id")};
// Optional params
boost::optional<std::size_t> maxBitRate {getParameterAs<std::size_t>(context.parameters, "maxBitRate")};
std::optional<std::size_t> maxBitRate {getParameterAs<std::size_t>(context.parameters, "maxBitRate")};
boost::filesystem::path trackPath;
std::filesystem::path trackPath;
{
auto transaction {context.dbSession.createSharedTransaction()};
@@ -1771,7 +1772,7 @@ handleGetCoverArt(RequestContext& context, Wt::Http::ResponseContinuation*)
// Mandatory params
Id id {getMandatoryParameterAs<Id>(context.parameters, "id")};
std::size_t size {getParameterAs<std::size_t>(context.parameters, "size").get_value_or(256)};
std::size_t size {getParameterAs<std::size_t>(context.parameters, "size").value_or(256)};
size = clamp(size, std::size_t {32}, std::size_t {1024});
MediaRetrievalResult res;
@@ -1861,7 +1862,7 @@ SubsonicResource::handleRequest(const Wt::Http::Request &request, Wt::Http::Resp
const Wt::Http::ParameterMap& parameters {request.getParameterMap()};
// Optional parameters
ResponseFormat format {getParameterAs<std::string>(parameters, "f").get_value_or("xml") == "json" ? ResponseFormat::json : ResponseFormat::xml};
const ResponseFormat format {getParameterAs<std::string>(parameters, "f").value_or("xml") == "json" ? ResponseFormat::json : ResponseFormat::xml};
try
{
+6 -5
View File
@@ -18,12 +18,13 @@
*/
#pragma once
#include <boost/optional.hpp>
#include <Wt/WResource.h>
#include <Wt/Http/Response.h>
#include "database/Database.hpp"
namespace Database
{
class Db;
}
namespace API::Subsonic
{
@@ -31,7 +32,7 @@ namespace API::Subsonic
class SubsonicResource final : public Wt::WResource
{
public:
SubsonicResource(Database::Database& db);
SubsonicResource(Database::Db& db);
~SubsonicResource();
static std::string getPath() { return "/rest/"; }
@@ -39,7 +40,7 @@ class SubsonicResource final : public Wt::WResource
void handleRequest(const Wt::Http::Request &request, Wt::Http::Response &response) override;
Database::Database& _db;
Database::Db& _db;
};
} // namespace
+3 -3
View File
@@ -62,7 +62,7 @@ AuthTokenService::createAuthToken(Database::Session& session, Database::IdType u
}
static
boost::optional<AuthTokenService::AuthTokenProcessResult::AuthTokenInfo>
std::optional<AuthTokenService::AuthTokenProcessResult::AuthTokenInfo>
processAuthToken(Database::Session& session, const std::string& secret)
{
const std::string secretHash {sha1Function.compute(secret, {})};
@@ -71,12 +71,12 @@ processAuthToken(Database::Session& session, const std::string& secret)
Database::AuthToken::pointer authToken {Database::AuthToken::getByValue(session, secretHash)};
if (!authToken)
return boost::none;
return std::nullopt;
if (authToken->getExpiry() < Wt::WDateTime::currentDateTime())
{
authToken.remove();
return boost::none;
return std::nullopt;
}
LMS_LOG(UI, DEBUG) << "Found auth token for user '" << authToken->getUser()->getLoginName() << "'!";
+3 -3
View File
@@ -21,9 +21,9 @@
#pragma once
#include <optional>
#include <string>
#include <boost/optional.hpp>
#include <boost/asio/ip/address.hpp>
#include "LoginThrottler.hpp"
@@ -69,8 +69,8 @@ namespace Auth {
Wt::WDateTime expiry;
};
State state;
boost::optional<AuthTokenInfo> authTokenInfo;
State state {State::NotFound};
std::optional<AuthTokenInfo> authTokenInfo {};
};
// Removed if found
+2 -2
View File
@@ -83,7 +83,7 @@ LoginThrottler::onGoodClientAttempt(const boost::asio::ip::address& address)
{
const boost::asio::ip::address clientAddress {getAddressToThrottle(address)};
_attemptsInfo.erase(address);
_attemptsInfo.erase(clientAddress);
}
bool
@@ -91,7 +91,7 @@ LoginThrottler::isClientThrottled(const boost::asio::ip::address& address) const
{
const boost::asio::ip::address clientAddress {getAddressToThrottle(address)};
auto it {_attemptsInfo.find(address)};
auto it {_attemptsInfo.find(clientAddress)};
if (it == _attemptsInfo.end())
return false;
+1 -2
View File
@@ -23,7 +23,6 @@
#include <string>
#include <boost/optional.hpp>
#include <boost/asio/ip/address.hpp>
#include "LoginThrottler.hpp"
@@ -81,7 +80,7 @@ namespace Auth {
};
State state;
boost::optional<AuthTokenInfo> authTokenInfo;
std::optional<AuthTokenInfo> authTokenInfo;
};
// Removed if found
+4 -12
View File
@@ -43,16 +43,8 @@ MediaFileException::MediaFileException(int avError)
{
}
void AvInit()
{
/* register all the codecs */
avcodec_register_all();
av_register_all();
LMS_LOG(AV, INFO) << "avcodec version = " << avcodec_version();
}
MediaFile::MediaFile(const boost::filesystem::path& p)
MediaFile::MediaFile(const std::filesystem::path& p)
: _p {p}
{
int error = avformat_open_input(&_context, _p.string().c_str(), nullptr, nullptr);
@@ -155,7 +147,7 @@ MediaFile::getStreamInfo() const
return res;
}
boost::optional<std::size_t>
std::optional<std::size_t>
MediaFile::getBestStream() const
{
int res = av_find_best_stream(_context,
@@ -166,7 +158,7 @@ MediaFile::getBestStream() const
0);
if (res < 0)
return boost::none;
return std::nullopt;
return res;
}
@@ -238,7 +230,7 @@ MediaFile::getAttachedPictures(std::size_t nbMaxPictures) const
return pictures;
}
boost::optional<MediaFileFormat> guessMediaFileFormat(const boost::filesystem::path& file)
std::optional<MediaFileFormat> guessMediaFileFormat(const std::filesystem::path& file)
{
AVOutputFormat* format {av_guess_format(NULL,file.string().c_str(),NULL)};
if (!format || !format->name)
+10 -12
View File
@@ -29,14 +29,12 @@ extern "C"
#include <libavutil/error.h>
}
#include <vector>
#include <string>
#include <cstdint>
#include <map>
#include <chrono>
#include <boost/optional.hpp>
#include <boost/filesystem/path.hpp>
#include <filesystem>
#include <map>
#include <optional>
#include <string>
#include <vector>
#include "AvTypes.hpp"
@@ -66,7 +64,7 @@ class MediaFileException : public AvException
class MediaFile
{
public:
MediaFile(const boost::filesystem::path& p);
MediaFile(const std::filesystem::path& p);
~MediaFile();
MediaFile(const MediaFile&) = delete;
@@ -76,19 +74,19 @@ class MediaFile
std::string getFormatName() const;
const boost::filesystem::path& getPath() const {return _p;};
const std::filesystem::path& getPath() const {return _p;};
std::chrono::milliseconds getDuration() const;
std::map<std::string, std::string> getMetaData(void);
std::vector<StreamInfo> getStreamInfo() const;
boost::optional<std::size_t> getBestStream() const; // none if failure/unknown
std::optional<std::size_t> getBestStream() const; // none if failure/unknown
bool hasAttachedPictures(void) const;
std::vector<Picture> getAttachedPictures(std::size_t nbMaxPictures) const;
private:
boost::filesystem::path _p;
std::filesystem::path _p;
AVFormatContext* _context {};
};
@@ -99,7 +97,7 @@ struct MediaFileFormat
std::string format;
};
boost::optional<MediaFileFormat> guessMediaFileFormat(const boost::filesystem::path& file);
std::optional<MediaFileFormat> guessMediaFileFormat(const std::filesystem::path& file);
} // namespace Av
+47 -47
View File
@@ -37,16 +37,15 @@ static const std::vector<std::string> execNames =
"ffmpeg",
};
static std::mutex transcoderMutex;
static boost::filesystem::path avConvPath = boost::filesystem::path();
static std::filesystem::path avConvPath = std::filesystem::path();
static std::atomic<size_t> globalId = {0};
void
Transcoder::init()
{
for (std::string execName : execNames)
for (const std::string& execName : execNames)
{
boost::filesystem::path p = searchExecPath(execName);
const std::filesystem::path p {searchExecPath(execName)};
if (!p.empty())
{
avConvPath = p;
@@ -60,11 +59,10 @@ Transcoder::init()
throw AvException("Cannot find any transcoder binary!");
}
Transcoder::Transcoder(boost::filesystem::path filePath, TranscodeParameters parameters)
: _filePath(filePath),
_parameters(parameters),
_isComplete(false),
_id(globalId++)
Transcoder::Transcoder(const std::filesystem::path& filePath, const TranscodeParameters& parameters)
: _filePath {filePath},
_parameters {parameters},
_id {globalId++}
{
}
@@ -72,84 +70,84 @@ Transcoder::Transcoder(boost::filesystem::path filePath, TranscodeParameters par
bool
Transcoder::start()
{
if (!boost::filesystem::exists(_filePath))
if (!std::filesystem::exists(_filePath))
return false;
else if (!boost::filesystem::is_regular( _filePath) )
else if (!std::filesystem::is_regular_file( _filePath) )
return false;
LMS_LOG_TRANSCODE(INFO) << "Transcoding file '" << _filePath.string() << "'";
std::vector<std::string> args;
args.push_back(avConvPath.string());
args.emplace_back(avConvPath.string());
// Make sure we do not produce anything in the stderr output
// in order not to block the whole forked process
args.push_back("-loglevel");
args.push_back("quiet");
args.push_back("-nostdin");
args.emplace_back("-loglevel");
args.emplace_back("quiet");
args.emplace_back("-nostdin");
// input Offset
if (_parameters.offset)
{
args.push_back("-ss");
args.push_back(std::to_string((*_parameters.offset).count()));
args.emplace_back("-ss");
args.emplace_back(std::to_string((*_parameters.offset).count()));
}
// Input file
args.push_back("-i");
args.push_back(_filePath.string());
args.emplace_back("-i");
args.emplace_back(_filePath.string());
// Stream mapping, if set
if (_parameters.stream)
{
args.push_back("-map");
args.push_back("0:" + std::to_string(*_parameters.stream));
args.emplace_back("-map");
args.emplace_back("0:" + std::to_string(*_parameters.stream));
}
if (_parameters.stripMetadata)
{
// Strip metadata
args.push_back("-map_metadata");
args.push_back("-1");
args.emplace_back("-map_metadata");
args.emplace_back("-1");
}
// Skip video flows (including covers)
args.push_back("-vn");
args.emplace_back("-vn");
// Codecs and formats
if (_parameters.encoding)
{
// Output bitrates
args.push_back("-b:a");
args.push_back(std::to_string(_parameters.bitrate));
args.emplace_back("-b:a");
args.emplace_back(std::to_string(_parameters.bitrate));
switch (*_parameters.encoding)
{
case Encoding::MP3:
args.push_back("-f");
args.push_back("mp3");
args.emplace_back("-f");
args.emplace_back("mp3");
break;
case Encoding::OGG_OPUS:
args.push_back("-acodec");
args.push_back("libopus");
args.push_back("-f");
args.push_back("ogg");
args.emplace_back("-acodec");
args.emplace_back("libopus");
args.emplace_back("-f");
args.emplace_back("ogg");
break;
case Encoding::OGG_VORBIS:
args.push_back("-acodec");
args.push_back("libvorbis");
args.push_back("-f");
args.push_back("ogg");
args.emplace_back("-acodec");
args.emplace_back("libvorbis");
args.emplace_back("-f");
args.emplace_back("ogg");
break;
case Encoding::WEBM_VORBIS:
args.push_back("-acodec");
args.push_back("libvorbis");
args.push_back("-f");
args.push_back("webm");
args.emplace_back("-acodec");
args.emplace_back("libvorbis");
args.emplace_back("-f");
args.emplace_back("webm");
break;
@@ -169,23 +167,25 @@ Transcoder::start()
return false;
}
args.push_back("-acodec");
args.push_back("copy");
args.push_back("-f");
args.push_back(mediaFileFormat->format);
args.emplace_back("-acodec");
args.emplace_back("copy");
args.emplace_back("-f");
args.emplace_back(mediaFileFormat->format);
_outputMimeType = mediaFileFormat->mimeType;
}
args.push_back("pipe:1");
args.emplace_back("pipe:1");
LMS_LOG_TRANSCODE(DEBUG) << "Dumping args (" << args.size() << ")";
for (std::string arg : args)
for (const std::string& arg : args)
LMS_LOG_TRANSCODE(DEBUG) << "Arg = '" << arg << "'";
// make sure only one thread is executing this part of code
{
std::lock_guard<std::mutex> lock(transcoderMutex);
static std::mutex transcoderMutex;
std::lock_guard<std::mutex> lock {transcoderMutex};
_child = std::make_shared<redi::ipstream>();
+17 -20
View File
@@ -20,12 +20,11 @@
#pragma once
#include <chrono>
#include <filesystem>
#include <optional>
#include <pstreams/pstream.h>
#include <boost/filesystem.hpp>
#include <boost/optional.hpp>
#include "AvTypes.hpp"
namespace Av {
@@ -34,10 +33,10 @@ namespace Av {
struct TranscodeParameters
{
boost::optional<Encoding> encoding; // If not set, no transcoding is performed
std::optional<Encoding> encoding; // If not set, no transcoding is performed
std::size_t bitrate {128000};
boost::optional<std::size_t> stream; // Id of the stream to be transcoded (auto detect by default)
boost::optional<std::chrono::seconds> offset {};
std::optional<std::size_t> stream; // Id of the stream to be transcoded (auto detect by default)
std::optional<std::chrono::seconds> offset {};
bool stripMetadata {true};
};
@@ -46,32 +45,30 @@ class Transcoder
public:
static void init();
Transcoder(boost::filesystem::path file, TranscodeParameters parameters);
Transcoder(const std::filesystem::path& file, const TranscodeParameters& parameters);
~Transcoder();
// non copyable
Transcoder(const Transcoder&) = delete;
Transcoder& operator=(const Transcoder&) = delete;
Transcoder(Transcoder&&) = delete;
Transcoder& operator=(Transcoder&&) = delete;
bool start();
const std::string& getOutputMimeType() const { return _outputMimeType; }
void process(std::vector<unsigned char>& output, std::size_t maxSize);
bool isComplete(void) const { return _isComplete; }
bool start();
const std::string& getOutputMimeType() const { return _outputMimeType; }
void process(std::vector<unsigned char>& output, std::size_t maxSize);
bool isComplete(void) const { return _isComplete; }
const TranscodeParameters& getParameters() const { return _parameters; }
private:
Transcoder();
boost::filesystem::path _filePath;
TranscodeParameters _parameters;
const std::filesystem::path _filePath;
const TranscodeParameters _parameters;
std::shared_ptr<redi::ipstream> _child;
bool _isComplete = false;
std::size_t _total = 0;
std::size_t _id;
bool _isComplete {};
std::size_t _total {};
const std::size_t _id {};
std::string _outputMimeType;
};
-1
View File
@@ -20,7 +20,6 @@
#pragma once
#include <string>
#include <boost/filesystem.hpp>
#include "utils/Exception.hpp"
+29 -29
View File
@@ -19,8 +19,6 @@
#include "CoverArtGrabber.hpp"
#include <boost/filesystem.hpp>
#include "av/AvInfo.hpp"
#include "database/Release.hpp"
@@ -32,9 +30,9 @@
namespace {
bool
isFileSupported(const boost::filesystem::path& file, const std::vector<boost::filesystem::path> extensions)
isFileSupported(const std::filesystem::path& file, const std::vector<std::filesystem::path> extensions)
{
boost::filesystem::path fileExtension = file.extension();
std::filesystem::path fileExtension = file.extension();
for (auto extension : extensions)
{
@@ -54,7 +52,7 @@ Grabber::Grabber()
}
void
Grabber::setDefaultCover(boost::filesystem::path p)
Grabber::setDefaultCover(const std::filesystem::path& p)
{
if (!_defaultCover.load(p))
throw LmsException("Cannot read default cover file '" + p.string() + "'");
@@ -84,7 +82,7 @@ Grabber::getDefaultCover(std::size_t size)
return it->second;
}
static boost::optional<Image::Image>
static std::optional<Image::Image>
getFromAvMediaFile(const Av::MediaFile& input)
{
std::vector<Image::Image> res;
@@ -100,11 +98,11 @@ getFromAvMediaFile(const Av::MediaFile& input)
}
LMS_LOG(COVER, DEBUG) << "No cover found in media file '" << input.getPath().string() << "'";
return boost::none;
return std::nullopt;
}
boost::optional<Image::Image>
Grabber::getFromDirectory(const boost::filesystem::path& p) const
std::optional<Image::Image>
Grabber::getFromDirectory(const std::filesystem::path& p) const
{
for (auto coverPath : getCoverPaths(p))
{
@@ -117,33 +115,33 @@ Grabber::getFromDirectory(const boost::filesystem::path& p) const
}
LMS_LOG(COVER, DEBUG) << "No cover found in directory '" << p.string() << "'";
return boost::none;
return std::nullopt;
}
std::vector<boost::filesystem::path>
Grabber::getCoverPaths(const boost::filesystem::path& directoryPath) const
std::vector<std::filesystem::path>
Grabber::getCoverPaths(const std::filesystem::path& directoryPath) const
{
std::vector<boost::filesystem::path> res;
boost::system::error_code ec;
std::vector<std::filesystem::path> res;
std::error_code ec;
// TODO handle preferred file names
boost::filesystem::directory_iterator itPath(directoryPath, ec);
boost::filesystem::directory_iterator itEnd;
std::filesystem::directory_iterator itPath(directoryPath, ec);
std::filesystem::directory_iterator itEnd;
while (!ec && itPath != itEnd)
{
boost::filesystem::path path = *itPath;
std::filesystem::path path = *itPath;
itPath.increment(ec);
if (!boost::filesystem::is_regular(path))
if (!std::filesystem::is_regular_file(path))
continue;
if (!isFileSupported(path, _fileExtensions))
continue;
if (boost::filesystem::file_size(path) > _maxFileSize)
if (std::filesystem::file_size(path) > _maxFileSize)
{
LMS_LOG(COVER, INFO) << "Cover file '" << path.string() << " is too big (" << boost::filesystem::file_size(path) << "), limit is " << _maxFileSize;
LMS_LOG(COVER, INFO) << "Cover file '" << path.string() << " is too big (" << std::filesystem::file_size(path) << "), limit is " << _maxFileSize;
continue;
}
@@ -153,8 +151,8 @@ Grabber::getCoverPaths(const boost::filesystem::path& directoryPath) const
return res;
}
boost::optional<Image::Image>
Grabber::getFromTrack(const boost::filesystem::path& p) const
std::optional<Image::Image>
Grabber::getFromTrack(const std::filesystem::path& p) const
{
try
{
@@ -165,7 +163,7 @@ Grabber::getFromTrack(const boost::filesystem::path& p) const
catch (Av::MediaFileException& e)
{
LMS_LOG(COVER, ERROR) << "Cannot get covers from track " << p.string() << ": " << e.what();
return boost::none;
return std::nullopt;
}
}
@@ -174,10 +172,10 @@ Grabber::getFromTrack(Database::Session& dbSession, Database::IdType trackId, st
{
using namespace Database;
boost::optional<Image::Image> cover;
std::optional<Image::Image> cover;
bool hasCover {};
boost::filesystem::path trackPath;
std::filesystem::path trackPath;
{
auto transaction {dbSession.createSharedTransaction()};
@@ -208,9 +206,9 @@ Grabber::getFromTrack(Database::Session& dbSession, Database::IdType trackId, st
Image::Image
Grabber::getFromRelease(Database::Session& session, Database::IdType releaseId, std::size_t size)
{
boost::optional<Image::Image> cover;
std::optional<Image::Image> cover;
boost::optional<Database::IdType> trackId;
std::optional<Database::IdType> trackId;
{
auto transaction {session.createSharedTransaction()};
@@ -239,7 +237,8 @@ Grabber::getFromTrack(Database::Session& session, Database::IdType trackId, Imag
{
const Image::Image cover {getFromTrack(session, trackId, size)};
return cover.save(Image::Format::JPEG);
assert(format == Image::Format::JPEG);
return cover.save(format);
}
std::vector<uint8_t>
@@ -247,7 +246,8 @@ Grabber::getFromRelease(Database::Session& session, Database::IdType releaseId,
{
const Image::Image cover {getFromRelease(session, releaseId, size)};
return cover.save(Image::Format::JPEG);
assert(format == Image::Format::JPEG);
return cover.save(format);
}
} // namespace CoverArt
+8 -8
View File
@@ -19,12 +19,12 @@
#pragma once
#include <filesystem>
#include <map>
#include <mutex>
#include <optional>
#include <vector>
#include <boost/optional.hpp>
#include "database/Types.hpp"
#include "image/Image.hpp"
@@ -44,7 +44,7 @@ class Grabber
Grabber(Grabber&&) = delete;
Grabber& operator=(Grabber&&) = delete;
void setDefaultCover(boost::filesystem::path defaultCoverPath);
void setDefaultCover(const std::filesystem::path& defaultCoverPath);
std::vector<uint8_t> getFromTrack(Database::Session& dbSession, Database::IdType trackId, Image::Format format, std::size_t size);
std::vector<uint8_t> getFromRelease(Database::Session& dbSession, Database::IdType releaseId, Image::Format format, std::size_t size);
@@ -54,9 +54,9 @@ class Grabber
Image::Image getFromTrack(Database::Session& dbSession, Database::IdType trackId, std::size_t size);
Image::Image getFromRelease(Database::Session& dbSession, Database::IdType releaseId, std::size_t size);
boost::optional<Image::Image> getFromTrack(const boost::filesystem::path& path) const;
std::vector<boost::filesystem::path> getCoverPaths(const boost::filesystem::path& directoryPath) const;
boost::optional<Image::Image> getFromDirectory(const boost::filesystem::path& path) const;
std::optional<Image::Image> getFromTrack(const std::filesystem::path& path) const;
std::vector<std::filesystem::path> getCoverPaths(const std::filesystem::path& directoryPath) const;
std::optional<Image::Image> getFromDirectory(const std::filesystem::path& path) const;
Image::Image getDefaultCover(std::size_t size);
@@ -65,12 +65,12 @@ class Grabber
std::mutex _mutex;
std::map<std::size_t /* size */, Image::Image> _defaultCovers;
std::vector<boost::filesystem::path> _fileExtensions
std::vector<std::filesystem::path> _fileExtensions
= {".jpg", ".jpeg", ".png", ".bmp"}; // TODO parametrize
std::size_t _maxFileSize = 5000000;
std::vector<boost::filesystem::path> _preferredFileNames
std::vector<std::filesystem::path> _preferredFileNames
= {"cover", "front"}; // TODO parametrize
};
+13 -8
View File
@@ -75,7 +75,7 @@ Artist::create(Session& session, const std::string& name, const std::string& MBI
}
std::vector<Artist::pointer>
Artist::getAll(Session& session, boost::optional<std::size_t> offset, boost::optional<std::size_t> size)
Artist::getAll(Session& session, std::optional<std::size_t> offset, std::optional<std::size_t> size)
{
session.checkSharedLocked();
Wt::Dbo::collection<pointer> res = session.getDboSession().find<Artist>()
@@ -151,8 +151,8 @@ std::vector<Artist::pointer>
Artist::getByFilter(Session& session,
const std::set<IdType>& clusters,
const std::vector<std::string>& keywords,
boost::optional<std::size_t> offset,
boost::optional<std::size_t> size,
std::optional<std::size_t> offset,
std::optional<std::size_t> size,
bool& moreResults)
{
session.checkSharedLocked();
@@ -174,7 +174,7 @@ Artist::getByFilter(Session& session,
}
std::vector<Artist::pointer>
Artist::getLastAdded(Session& session, Wt::WDateTime after, boost::optional<std::size_t> limit)
Artist::getLastAdded(Session& session, Wt::WDateTime after, std::optional<std::size_t> limit)
{
session.checkSharedLocked();
Wt::Dbo::collection<Artist::pointer> res = session.getDboSession().query<Artist::pointer>("SELECT a from artist a INNER JOIN track_artist_link t_a_l ON t_a_l.artist_id = a.id INNER JOIN track t ON t.id = t_a_l.track_id")
@@ -243,7 +243,7 @@ Artist::getReleaseCount() const
}
std::vector<Wt::Dbo::ptr<Track>>
Artist::getTracks(boost::optional<TrackArtistLink::Type> linkType) const
Artist::getTracks(std::optional<TrackArtistLink::Type> linkType) const
{
assert(self());
assert(IdIsValid(self()->id()));
@@ -262,22 +262,27 @@ Artist::getTracks(boost::optional<TrackArtistLink::Type> linkType) const
}
std::vector<Wt::Dbo::ptr<Track>>
Artist::getTracksWithRelease(boost::optional<TrackArtistLink::Type> linkType) const
Artist::getTracksWithRelease(std::optional<TrackArtistLink::Type> linkType) const
{
assert(self());
assert(IdIsValid(self()->id()));
assert(session());
Wt::Dbo::collection<Wt::Dbo::ptr<Track>> tracks {session()->query<Wt::Dbo::ptr<Track>>("SELECT t FROM track t INNER JOIN artist a ON a.id = t_a_l.artist_id INNER JOIN track_artist_link t_a_l ON t_a_l.track_id = t.id INNER JOIN release r ON r.id = t.release_id")
auto query {session()->query<Wt::Dbo::ptr<Track>>("SELECT t FROM track t INNER JOIN artist a ON a.id = t_a_l.artist_id INNER JOIN track_artist_link t_a_l ON t_a_l.track_id = t.id INNER JOIN release r ON r.id = t.release_id")
.where("a.id = ?").bind(self()->id())
.orderBy("t.year,r.name,t.disc_number,t.track_number")};
if (linkType)
query.where("t_a_l.type = ?").bind(*linkType);
Wt::Dbo::collection<Wt::Dbo::ptr<Track>> tracks {query.resultList()};
return std::vector<Wt::Dbo::ptr<Track>>(tracks.begin(), tracks.end());
}
std::vector<Wt::Dbo::ptr<Track>>
Artist::getRandomTracks(boost::optional<std::size_t> count) const
Artist::getRandomTracks(std::optional<std::size_t> count) const
{
assert(self());
assert(IdIsValid(self()->id()));
+8 -9
View File
@@ -19,11 +19,10 @@
#pragma once
#include <optional>
#include <string>
#include <vector>
#include <boost/optional.hpp>
#include <Wt/WDateTime.h>
#include <Wt/Dbo/Dbo.h>
@@ -58,13 +57,13 @@ class Artist : public Wt::Dbo::Dbo<Artist>
static std::vector<pointer> getByFilter(Session& session,
const std::set<IdType>& clusters, // at least one track that belongs to these clusters
const std::vector<std::string>& keywords, // name must match all of these keywords
boost::optional<std::size_t> offset,
boost::optional<std::size_t> size,
std::optional<std::size_t> offset,
std::optional<std::size_t> size,
bool& moreExpected);
static std::vector<pointer> getAll(Session& session, boost::optional<std::size_t> offset = {}, boost::optional<std::size_t> size = {});
static std::vector<pointer> getAll(Session& session, std::optional<std::size_t> offset = {}, std::optional<std::size_t> size = {});
static std::vector<pointer> getAllOrphans(Session& session); // No track related
static std::vector<pointer> getLastAdded(Session& session, Wt::WDateTime after, boost::optional<std::size_t> size = {});
static std::vector<pointer> getLastAdded(Session& session, Wt::WDateTime after, std::optional<std::size_t> size = {});
// Accessors
const std::string& getName(void) const { return _name; }
@@ -72,9 +71,9 @@ class Artist : public Wt::Dbo::Dbo<Artist>
std::vector<Wt::Dbo::ptr<Release>> getReleases(const std::set<IdType>& clusterIds = std::set<IdType>()) const;
std::size_t getReleaseCount() const;
std::vector<Wt::Dbo::ptr<Track>> getTracks(boost::optional<TrackArtistLink::Type> linkType = {}) const;
std::vector<Wt::Dbo::ptr<Track>> getTracksWithRelease(boost::optional<TrackArtistLink::Type> linkType = {}) const;
std::vector<Wt::Dbo::ptr<Track>> getRandomTracks(boost::optional<std::size_t> count) const;
std::vector<Wt::Dbo::ptr<Track>> getTracks(std::optional<TrackArtistLink::Type> linkType = {}) const;
std::vector<Wt::Dbo::ptr<Track>> getTracksWithRelease(std::optional<TrackArtistLink::Type> linkType = {}) const;
std::vector<Wt::Dbo::ptr<Track>> getRandomTracks(std::optional<std::size_t> count) const;
// Get the cluster of the tracks made by this artist
// Each clusters are grouped by cluster type, sorted by the number of occurence
@@ -17,7 +17,7 @@
* along with LMS. If not, see <http://www.gnu.org/licenses/>.
*/
#include "Database.hpp"
#include "Db.hpp"
#include <Wt/Dbo/FixedSqlConnectionPool.h>
#include <Wt/Dbo/backend/Sqlite3.h>
@@ -28,7 +28,7 @@
namespace Database {
// Session living class handling the database and the login
Database::Database(const boost::filesystem::path& dbPath)
Db::Db(const std::filesystem::path& dbPath)
{
LMS_LOG(DB, INFO) << "Creating connection pool on file " << dbPath.string();
@@ -49,9 +49,9 @@ Database::Database(const boost::filesystem::path& dbPath)
}
std::unique_ptr<Session>
Database::createSession()
Db::createSession()
{
return std::unique_ptr<Session>{new Session {_sharedMutex, *_connectionPool.get()}};
return std::unique_ptr<Session>(new Session {_sharedMutex, *_connectionPool.get()});
}
} // namespace Database
@@ -19,10 +19,9 @@
#pragma once
#include <filesystem>
#include <shared_mutex>
#include <boost/filesystem.hpp>
#include <Wt/Dbo/SqlConnectionPool.h>
#include "Session.hpp"
@@ -30,17 +29,17 @@
namespace Database {
// Session living class handling the database and the login
class Database
class Db
{
public:
Database(const boost::filesystem::path& dbPath);
Db(const std::filesystem::path& dbPath);
std::unique_ptr<Session> createSession();
private:
std::shared_timed_mutex _sharedMutex;
std::unique_ptr<Wt::Dbo::SqlConnectionPool> _connectionPool;
std::shared_mutex _sharedMutex;
std::unique_ptr<Wt::Dbo::SqlConnectionPool> _connectionPool;
};
} // namespace Database
+18 -18
View File
@@ -84,7 +84,7 @@ Release::getCount(Session& session)
}
std::vector<Release::pointer>
Release::getAll(Session& session, boost::optional<std::size_t> offset, boost::optional<std::size_t> size)
Release::getAll(Session& session, std::optional<std::size_t> offset, std::optional<std::size_t> size)
{
session.checkSharedLocked();
@@ -97,7 +97,7 @@ Release::getAll(Session& session, boost::optional<std::size_t> offset, boost::op
}
std::vector<Release::pointer>
Release::getAllOrderedByArtist(Session& session, boost::optional<std::size_t> offset, boost::optional<std::size_t> size)
Release::getAllOrderedByArtist(Session& session, std::optional<std::size_t> offset, std::optional<std::size_t> size)
{
session.checkSharedLocked();
@@ -114,7 +114,7 @@ Release::getAllOrderedByArtist(Session& session, boost::optional<std::size_t> of
}
std::vector<Release::pointer>
Release::getAllRandom(Session& session, boost::optional<std::size_t> size)
Release::getAllRandom(Session& session, std::optional<std::size_t> size)
{
session.checkSharedLocked();
@@ -136,7 +136,7 @@ Release::getAllOrphans(Session& session)
}
std::vector<Release::pointer>
Release::getLastAdded(Session& session, const Wt::WDateTime& after, boost::optional<std::size_t> offset, boost::optional<std::size_t> limit)
Release::getLastAdded(Session& session, const Wt::WDateTime& after, std::optional<std::size_t> offset, std::optional<std::size_t> limit)
{
session.checkSharedLocked();
@@ -151,7 +151,7 @@ Release::getLastAdded(Session& session, const Wt::WDateTime& after, boost::optio
}
std::vector<Release::pointer>
Release::getByYear(Session& session, int yearFrom, int yearTo, boost::optional<std::size_t> offset, boost::optional<std::size_t> limit)
Release::getByYear(Session& session, int yearFrom, int yearTo, std::optional<std::size_t> offset, std::optional<std::size_t> limit)
{
Wt::Dbo::collection<Release::pointer> res = session.getDboSession().query<Release::pointer>
("SELECT DISTINCT r from release r INNER JOIN track t ON r.id = t.release_id")
@@ -216,8 +216,8 @@ std::vector<Release::pointer>
Release::getByFilter(Session& session,
const std::set<IdType>& clusterIds,
const std::vector<std::string>& keywords,
boost::optional<std::size_t> offset,
boost::optional<std::size_t> size,
std::optional<std::size_t> offset,
std::optional<std::size_t> size,
bool& moreResults)
{
Wt::Dbo::collection<pointer> collection = getQuery(session, clusterIds, keywords)
@@ -237,19 +237,19 @@ Release::getByFilter(Session& session,
return res;
}
boost::optional<std::size_t>
std::optional<std::size_t>
Release::getTotalTrackNumber(void) const
{
return (_totalTrackNumber > 0) ? boost::make_optional<std::size_t>(_totalTrackNumber) : boost::none;
return (_totalTrackNumber > 0) ? std::make_optional<std::size_t>(_totalTrackNumber) : std::nullopt;
}
boost::optional<std::size_t>
std::optional<std::size_t>
Release::getTotalDiscNumber(void) const
{
return (_totalDiscNumber > 0) ? boost::make_optional<std::size_t>(_totalDiscNumber) : boost::none;
return (_totalDiscNumber > 0) ? std::make_optional<std::size_t>(_totalDiscNumber) : std::nullopt;
}
boost::optional<int>
std::optional<int>
Release::getReleaseYear(bool original) const
{
assert(session());
@@ -264,17 +264,17 @@ Release::getReleaseYear(bool original) const
// various dates => no date
if (dates.empty() || dates.size() > 1)
return boost::none;
return std::nullopt;
auto date {dates.front()};
if (date > 0)
return date;
else
return boost::none;
return std::nullopt;
}
boost::optional<std::string>
std::optional<std::string>
Release::getCopyright() const
{
assert(session());
@@ -289,12 +289,12 @@ Release::getCopyright() const
// various copyrights => no copyright
if (values.empty() || values.size() > 1 || values.front().empty())
return boost::none;
return std::nullopt;
return values.front();
}
boost::optional<std::string>
std::optional<std::string>
Release::getCopyrightURL() const
{
assert(session());
@@ -309,7 +309,7 @@ Release::getCopyrightURL() const
// various copyright URLs => no copyright URL
if (values.empty() || values.size() > 1 || values.front().empty())
return boost::none;
return std::nullopt;
return values.front();
}
+13 -13
View File
@@ -19,7 +19,7 @@
#pragma once
#include <boost/optional.hpp>
#include <optional>
#include <Wt/Dbo/WtSqlTraits.h>
@@ -51,18 +51,18 @@ class Release : public Wt::Dbo::Dbo<Release>
static std::vector<pointer> getByName(Session& session, const std::string& name);
static pointer getById(Session& session, IdType id);
static std::vector<pointer> getAllOrphans(Session& session); // no track related
static std::vector<pointer> getAll(Session& session, boost::optional<std::size_t> offset = {}, boost::optional<std::size_t> size = {});
static std::vector<pointer> getAllOrderedByArtist(Session& session, boost::optional<std::size_t> offset = {}, boost::optional<std::size_t> size = {});
static std::vector<pointer> getAllRandom(Session& session, boost::optional<std::size_t> size = {});
static std::vector<pointer> getLastAdded(Session& session, const Wt::WDateTime& after, boost::optional<std::size_t> offset = {}, boost::optional<std::size_t> size = {});
static std::vector<pointer> getByYear(Session& session, int yearFrom, int yearTo, boost::optional<std::size_t> offset = {}, boost::optional<std::size_t> size = {});
static std::vector<pointer> getAll(Session& session, std::optional<std::size_t> offset = {}, std::optional<std::size_t> size = {});
static std::vector<pointer> getAllOrderedByArtist(Session& session, std::optional<std::size_t> offset = {}, std::optional<std::size_t> size = {});
static std::vector<pointer> getAllRandom(Session& session, std::optional<std::size_t> size = {});
static std::vector<pointer> getLastAdded(Session& session, const Wt::WDateTime& after, std::optional<std::size_t> offset = {}, std::optional<std::size_t> size = {});
static std::vector<pointer> getByYear(Session& session, int yearFrom, int yearTo, std::optional<std::size_t> offset = {}, std::optional<std::size_t> size = {});
static std::vector<pointer> getByFilter(Session& session, const std::set<IdType>& clusters);
static std::vector<pointer> getByFilter(Session& session,
const std::set<IdType>& clusters, // at least one track that belongs to these clusters
const std::vector<std::string>& keywords, // name must match all of these keywords
boost::optional<std::size_t> offset,
boost::optional<std::size_t> size,
std::optional<std::size_t> offset,
std::optional<std::size_t> size,
bool& moreExpected);
std::vector<Wt::Dbo::ptr<Track>> getTracks(const std::set<IdType>& clusters = std::set<IdType>()) const;
@@ -77,9 +77,9 @@ class Release : public Wt::Dbo::Dbo<Release>
static pointer create(Session& session, const std::string& name, const std::string& MBID = "");
// Utility functions
boost::optional<int> getReleaseYear(bool originalDate = false) const; // 0 if unknown or various
boost::optional<std::string> getCopyright() const;
boost::optional<std::string> getCopyrightURL() const;
std::optional<int> getReleaseYear(bool originalDate = false) const; // 0 if unknown or various
std::optional<std::string> getCopyright() const;
std::optional<std::string> getCopyrightURL() const;
// Modifiers
void setTotalDiscNumber(std::size_t num) { _totalDiscNumber = static_cast<int>(num); }
@@ -88,8 +88,8 @@ class Release : public Wt::Dbo::Dbo<Release>
// Accessors
std::string getName() const { return _name; }
std::string getMBID() const { return _MBID; }
boost::optional<std::size_t> getTotalTrackNumber() const;
boost::optional<std::size_t> getTotalDiscNumber() const;
std::optional<std::size_t> getTotalTrackNumber() const;
std::optional<std::size_t> getTotalDiscNumber() const;
std::chrono::milliseconds getDuration() const;
// Get the artists of this release
+4 -4
View File
@@ -62,11 +62,11 @@ ScanSettings::get(Session& session)
return session.getDboSession().find<ScanSettings>();
}
std::set<boost::filesystem::path>
std::set<std::filesystem::path>
ScanSettings::getAudioFileExtensions() const
{
auto extensions = splitString(_audioFileExtensions, " ");
return std::set<boost::filesystem::path>(std::cbegin(extensions), std::cend(extensions));
return std::set<std::filesystem::path>(std::cbegin(extensions), std::cend(extensions));
}
std::vector<ClusterType::pointer>
@@ -76,7 +76,7 @@ ScanSettings::getClusterTypes() const
}
void
ScanSettings::setMediaDirectory(boost::filesystem::path p)
ScanSettings::setMediaDirectory(std::filesystem::path p)
{
_mediaDirectory = stringTrimEnd(p.string(), "/\\");
}
@@ -85,7 +85,7 @@ template <typename It>
std::set<std::string> getNames(It begin, It end)
{
std::set<std::string> names;
std::transform(begin, end, std::inserter(names, std::begin(names)),
std::transform(begin, end, std::inserter(names, std::cbegin(names)),
[](const ClusterType::pointer& clusterType)
{
return clusterType->getName();
+5 -5
View File
@@ -19,7 +19,7 @@
#pragma once
#include <boost/filesystem.hpp>
#include <filesystem>
#include <Wt/Dbo/Dbo.h>
#include <Wt/WTime.h>
@@ -47,18 +47,18 @@ class ScanSettings : public Wt::Dbo::Dbo<ScanSettings>
// Getters
std::size_t getScanVersion() const { return _scanVersion; }
boost::filesystem::path getMediaDirectory() const { return _mediaDirectory; }
std::filesystem::path getMediaDirectory() const { return _mediaDirectory; }
Wt::WTime getUpdateStartTime() const { return _startTime; }
UpdatePeriod getUpdatePeriod() const { return _updatePeriod; }
std::vector<Wt::Dbo::ptr<ClusterType>> getClusterTypes() const;
std::set<boost::filesystem::path> getAudioFileExtensions() const;
std::set<std::filesystem::path> getAudioFileExtensions() const;
// Setters
void setMediaDirectory(boost::filesystem::path p);
void setMediaDirectory(std::filesystem::path p);
void setUpdateStartTime(Wt::WTime t) { _startTime = t; }
void setUpdatePeriod(UpdatePeriod p) { _updatePeriod = p; }
void setClusterTypes(Session& session, const std::set<std::string>& clusterTypeNames);
void setAudioFileExtensions(std::set<boost::filesystem::path> fileExtensions);
void setAudioFileExtensions(std::set<std::filesystem::path> fileExtensions);
template<class Action>
void persist(Action& a)
+8 -8
View File
@@ -110,7 +110,7 @@ Session::doDatabaseMigrationIfNeeded()
VersionInfo::get(*this).modify()->setVersion(LMS_DATABASE_VERSION);
}
Session::Session(std::shared_timed_mutex& mutex, Wt::Dbo::SqlConnectionPool& connectionPool)
Session::Session(std::shared_mutex& mutex, Wt::Dbo::SqlConnectionPool& connectionPool)
: _mutex {mutex}
{
_session.setConnectionPool(connectionPool);
@@ -140,9 +140,9 @@ enum class OwnedLock
Unique,
};
static thread_local std::map<std::shared_timed_mutex*, OwnedLock> lockDebug;
static thread_local std::map<std::shared_mutex*, OwnedLock> lockDebug;
UniqueTransaction::UniqueTransaction(std::shared_timed_mutex& mutex, Wt::Dbo::Session& session)
UniqueTransaction::UniqueTransaction(std::shared_mutex& mutex, Wt::Dbo::Session& session)
: _lock {mutex},
_transaction {session}
{
@@ -156,7 +156,7 @@ UniqueTransaction::~UniqueTransaction()
lockDebug[_lock.mutex()] = OwnedLock::None;
}
SharedTransaction::SharedTransaction(std::shared_timed_mutex& mutex, Wt::Dbo::Session& session)
SharedTransaction::SharedTransaction(std::shared_mutex& mutex, Wt::Dbo::Session& session)
: _lock {mutex},
_transaction {session}
{
@@ -182,16 +182,16 @@ Session::checkSharedLocked()
assert(lockDebug[&_mutex] != OwnedLock::None);
}
std::unique_ptr<UniqueTransaction>
UniqueTransaction
Session::createUniqueTransaction()
{
return std::unique_ptr<UniqueTransaction>(new UniqueTransaction{_mutex, _session});
return UniqueTransaction{_mutex, _session};
}
std::unique_ptr<SharedTransaction>
SharedTransaction
Session::createSharedTransaction()
{
return std::unique_ptr<SharedTransaction>(new SharedTransaction{_mutex, _session});
return SharedTransaction{_mutex, _session};
}
void
+10 -11
View File
@@ -21,7 +21,6 @@
#include <shared_mutex>
#include <mutex>
#include <boost/filesystem.hpp>
#include <memory>
#include <Wt/Dbo/Dbo.h>
@@ -36,9 +35,9 @@ class UniqueTransaction
private:
friend class Session;
UniqueTransaction(std::shared_timed_mutex& mutex, Wt::Dbo::Session& session);
UniqueTransaction(std::shared_mutex& mutex, Wt::Dbo::Session& session);
std::unique_lock<std::shared_timed_mutex> _lock;
std::unique_lock<std::shared_mutex> _lock;
Wt::Dbo::Transaction _transaction;
};
@@ -49,9 +48,9 @@ class SharedTransaction
private:
friend class Session;
SharedTransaction(std::shared_timed_mutex& mutex, Wt::Dbo::Session& session);
SharedTransaction(std::shared_mutex& mutex, Wt::Dbo::Session& session);
std::shared_lock<std::shared_timed_mutex> _lock;
std::shared_lock<std::shared_mutex> _lock;
Wt::Dbo::Transaction _transaction;
};
@@ -63,8 +62,8 @@ class Session
Session& operator=(const Session&) = delete;
Session& operator=(Session&&) = delete;
std::unique_ptr<UniqueTransaction> createUniqueTransaction();
std::unique_ptr<SharedTransaction> createSharedTransaction();
UniqueTransaction createUniqueTransaction();
SharedTransaction createSharedTransaction();
void checkUniqueLocked();
void checkSharedLocked();
@@ -74,15 +73,15 @@ class Session
Wt::Dbo::Session& getDboSession() { return _session; }
private:
friend class Database;
friend class Db;
Session(std::shared_timed_mutex& mutex, Wt::Dbo::SqlConnectionPool& connectionPool);
Session(std::shared_mutex& mutex, Wt::Dbo::SqlConnectionPool& connectionPool);
void doDatabaseMigrationIfNeeded();
void prepareTables(); // need to run only once at startup
std::shared_timed_mutex& _mutex;
Wt::Dbo::Session _session;
std::shared_mutex& _mutex;
Wt::Dbo::Session _session;
};
} // namespace Database
+23 -23
View File
@@ -32,14 +32,14 @@
namespace Database {
Track::Track(const boost::filesystem::path& p)
Track::Track(const std::filesystem::path& p)
:
_filePath( p.string() )
{
}
std::vector<Track::pointer>
Track::getAll(Session& session, boost::optional<std::size_t> limit)
Track::getAll(Session& session, std::optional<std::size_t> limit)
{
session.checkSharedLocked();
@@ -50,7 +50,7 @@ Track::getAll(Session& session, boost::optional<std::size_t> limit)
}
std::vector<Track::pointer>
Track::getAllRandom(Session& session, boost::optional<std::size_t> limit)
Track::getAllRandom(Session& session, std::optional<std::size_t> limit)
{
session.checkSharedLocked();
@@ -71,7 +71,7 @@ Track::getAllIds(Session& session)
}
Track::pointer
Track::getByPath(Session& session, const boost::filesystem::path& p)
Track::getByPath(Session& session, const std::filesystem::path& p)
{
session.checkSharedLocked();
@@ -97,7 +97,7 @@ Track::getByMBID(Session& session, const std::string& mbid)
}
Track::pointer
Track::create(Session& session, const boost::filesystem::path& p)
Track::create(Session& session, const std::filesystem::path& p)
{
session.checkUniqueLocked();
@@ -107,13 +107,13 @@ Track::create(Session& session, const boost::filesystem::path& p)
return res;
}
std::vector<boost::filesystem::path>
std::vector<std::filesystem::path>
Track::getAllPaths(Session& session)
{
session.checkSharedLocked();
Wt::Dbo::collection<std::string> res = session.getDboSession().query<std::string>("SELECT file_path FROM track");
return std::vector<boost::filesystem::path>(res.begin(), res.end());
return std::vector<std::filesystem::path>(res.begin(), res.end());
}
std::vector<Track::pointer>
@@ -126,7 +126,7 @@ Track::getMBIDDuplicates(Session& session)
}
std::vector<Track::pointer>
Track::getLastAdded(Session& session, const Wt::WDateTime& after, boost::optional<std::size_t> limit)
Track::getLastAdded(Session& session, const Wt::WDateTime& after, std::optional<std::size_t> limit)
{
session.checkSharedLocked();
@@ -151,7 +151,7 @@ Track::getAllWithMBIDAndMissingFeatures(Session& session)
}
std::vector<IdType>
Track::getAllIdsWithFeatures(Session& session, boost::optional<std::size_t> limit)
Track::getAllIdsWithFeatures(Session& session, std::optional<std::size_t> limit)
{
session.checkSharedLocked();
@@ -224,8 +224,8 @@ std::vector<Track::pointer>
Track::getByFilter(Session& session,
const std::set<IdType>& clusterIds,
const std::vector<std::string>& keywords,
boost::optional<std::size_t> offset,
boost::optional<std::size_t> size,
std::optional<std::size_t> offset,
std::optional<std::size_t> size,
bool& moreResults)
{
session.checkSharedLocked();
@@ -289,40 +289,40 @@ Track::setFeatures(const Wt::Dbo::ptr<TrackFeatures>& features)
_trackFeatures = features;
}
boost::optional<std::size_t>
std::optional<std::size_t>
Track::getTrackNumber(void) const
{
return (_trackNumber > 0) ? boost::make_optional<std::size_t>(_trackNumber) : boost::none;
return (_trackNumber > 0) ? std::make_optional<std::size_t>(_trackNumber) : std::nullopt;
}
boost::optional<std::size_t>
std::optional<std::size_t>
Track::getDiscNumber(void) const
{
return (_discNumber > 0) ? boost::make_optional<std::size_t>(_discNumber) : boost::none;
return (_discNumber > 0) ? std::make_optional<std::size_t>(_discNumber) : std::nullopt;
}
boost::optional<int>
std::optional<int>
Track::getYear() const
{
return (_year > 0) ? boost::make_optional<int>(_year) : boost::none;
return (_year > 0) ? std::make_optional<int>(_year) : std::nullopt;
}
boost::optional<int>
std::optional<int>
Track::getOriginalYear() const
{
return (_originalYear > 0) ? boost::make_optional<int>(_originalYear) : boost::none;
return (_originalYear > 0) ? std::make_optional<int>(_originalYear) : std::nullopt;
}
boost::optional<std::string>
std::optional<std::string>
Track::getCopyright() const
{
return _copyright != "" ? boost::make_optional<std::string>(_copyright) : boost::none;
return _copyright != "" ? std::make_optional<std::string>(_copyright) : std::nullopt;
}
boost::optional<std::string>
std::optional<std::string>
Track::getCopyrightURL() const
{
return _copyrightURL != "" ? boost::make_optional<std::string>(_copyrightURL) : boost::none;
return _copyrightURL != "" ? std::make_optional<std::string>(_copyrightURL) : std::nullopt;
}
std::vector<Wt::Dbo::ptr<Artist>>
+22 -23
View File
@@ -19,12 +19,11 @@
#pragma once
#include <string>
#include <vector>
#include <chrono>
#include <boost/filesystem.hpp>
#include <boost/optional.hpp>
#include <filesystem>
#include <optional>
#include <vector>
#include <string>
#include <Wt/Dbo/Dbo.h>
#include <Wt/WDateTime.h>
@@ -50,10 +49,10 @@ class Track : public Wt::Dbo::Dbo<Track>
using pointer = Wt::Dbo::ptr<Track>;
Track() {}
Track(const boost::filesystem::path& p);
Track(const std::filesystem::path& p);
// Find utility functions
static pointer getByPath(Session& session, const boost::filesystem::path& p);
static pointer getByPath(Session& session, const std::filesystem::path& p);
static pointer getById(Session& session, IdType id);
static pointer getByMBID(Session& session, const std::string& MBID);
static std::vector<pointer> getByFilter(Session& session,
@@ -61,21 +60,21 @@ class Track : public Wt::Dbo::Dbo<Track>
static std::vector<pointer> getByFilter(Session& session,
const std::set<IdType>& clusters, // tracks that belong to these clusters
const std::vector<std::string>& keywords, // name must match all of these keywords
boost::optional<std::size_t> offset,
boost::optional<std::size_t> size,
std::optional<std::size_t> offset,
std::optional<std::size_t> size,
bool& moreExpected);
static std::vector<pointer> getAll(Session& session, boost::optional<std::size_t> limit = {});
static std::vector<pointer> getAllRandom(Session& session, boost::optional<std::size_t> limit = {});
static std::vector<pointer> getAll(Session& session, std::optional<std::size_t> limit = {});
static std::vector<pointer> getAllRandom(Session& session, std::optional<std::size_t> limit = {});
static std::vector<IdType> getAllIds(Session& session); // nested transaction
static std::vector<boost::filesystem::path> getAllPaths(Session& session); // nested transaction
static std::vector<std::filesystem::path> getAllPaths(Session& session); // nested transaction
static std::vector<pointer> getMBIDDuplicates(Session& session);
static std::vector<pointer> getLastAdded(Session& session, const Wt::WDateTime& after, boost::optional<std::size_t> size = 1);
static std::vector<pointer> getLastAdded(Session& session, const Wt::WDateTime& after, std::optional<std::size_t> size = 1);
static std::vector<pointer> getAllWithMBIDAndMissingFeatures(Session& session);
static std::vector<IdType> getAllIdsWithFeatures(Session& session, boost::optional<std::size_t> limit = {});
static std::vector<IdType> getAllIdsWithFeatures(Session& session, std::optional<std::size_t> limit = {});
// Create utility
static pointer create(Session& session, const boost::filesystem::path& p);
static pointer create(Session& session, const std::filesystem::path& p);
// Accessors
void setScanVersion(std::size_t version) { _scanVersion = version; }
@@ -98,20 +97,20 @@ class Track : public Wt::Dbo::Dbo<Track>
void setFeatures(const Wt::Dbo::ptr<TrackFeatures>& features);
std::size_t getScanVersion() const { return _scanVersion; }
boost::optional<std::size_t> getTrackNumber() const;
boost::optional<std::size_t> getDiscNumber() const;
std::optional<std::size_t> getTrackNumber() const;
std::optional<std::size_t> getDiscNumber() const;
std::string getName() const { return _name; }
boost::filesystem::path getPath() const { return _filePath; }
std::filesystem::path getPath() const { return _filePath; }
std::chrono::milliseconds getDuration() const { return _duration; }
boost::optional<int> getYear() const;
boost::optional<int> getOriginalYear() const;
std::optional<int> getYear() const;
std::optional<int> getOriginalYear() const;
Wt::WDateTime getLastWriteTime() const { return _fileLastWrite; }
Wt::WDateTime getAddedTime() const { return _fileAdded; }
bool hasCover() const { return _hasCover; }
const std::string& getMBID() const { return _MBID; }
boost::optional<std::string> getCopyright() const;
boost::optional<std::string> getCopyrightURL() const;
std::vector<Wt::Dbo::ptr<Artist>> getArtists(TrackArtistLink::Type type = {TrackArtistLink::Type::Artist}) const;
std::optional<std::string> getCopyright() const;
std::optional<std::string> getCopyrightURL() const;
std::vector<Wt::Dbo::ptr<Artist>> getArtists(TrackArtistLink::Type type = TrackArtistLink::Type::Artist) const;
std::vector<Wt::Dbo::ptr<TrackArtistLink>> getArtistLinks() const;
Wt::Dbo::ptr<Release> getRelease() const { return _release; }
std::vector<Wt::Dbo::ptr<Cluster>> getClusters() const;
+2 -2
View File
@@ -100,7 +100,7 @@ TrackList::getById(Session& session, IdType id)
std::vector<Wt::Dbo::ptr<TrackListEntry>>
TrackList::getEntries(boost::optional<std::size_t> offset, boost::optional<std::size_t> size) const
TrackList::getEntries(std::optional<std::size_t> offset, std::optional<std::size_t> size) const
{
assert(session());
assert(IdIsValid(self()->id()));
@@ -116,7 +116,7 @@ TrackList::getEntries(boost::optional<std::size_t> offset, boost::optional<std::
}
std::vector<Wt::Dbo::ptr<TrackListEntry>>
TrackList::getEntriesReverse(boost::optional<std::size_t> offset, boost::optional<std::size_t> size) const
TrackList::getEntriesReverse(std::optional<std::size_t> offset, std::optional<std::size_t> size) const
{
assert(session());
assert(IdIsValid(self()->id()));
+4 -5
View File
@@ -19,12 +19,11 @@
#pragma once
#include <boost/optional.hpp>
#include <optional>
#include <string>
#include <Wt/Dbo/Dbo.h>
#include <string>
#include "Types.hpp"
namespace Database {
@@ -79,8 +78,8 @@ class TrackList : public Wt::Dbo::Dbo<TrackList>
// Get tracks, ordered by position
std::size_t getCount() const;
Wt::Dbo::ptr<TrackListEntry> getEntry(std::size_t pos) const;
std::vector<Wt::Dbo::ptr<TrackListEntry>> getEntries(boost::optional<std::size_t> offset = {}, boost::optional<std::size_t> size = {}) const;
std::vector<Wt::Dbo::ptr<TrackListEntry>> getEntriesReverse(boost::optional<std::size_t> offset = {}, boost::optional<std::size_t> size = {}) const;
std::vector<Wt::Dbo::ptr<TrackListEntry>> getEntries(std::optional<std::size_t> offset = {}, std::optional<std::size_t> size = {}) const;
std::vector<Wt::Dbo::ptr<TrackListEntry>> getEntriesReverse(std::optional<std::size_t> offset = {}, std::optional<std::size_t> size = {}) const;
std::vector<IdType> getTrackIds() const;
+1 -1
View File
@@ -247,7 +247,7 @@ User::hasStarredRelease(Wt::Dbo::ptr<Release> release) const
}
std::vector<Wt::Dbo::ptr<Release>>
User::getStarredReleases(boost::optional<std::size_t> offset, boost::optional<std::size_t> limit) const
User::getStarredReleases(std::optional<std::size_t> offset, std::optional<std::size_t> limit) const
{
Wt::Dbo::collection<Wt::Dbo::ptr<Release>> res = _starredReleases.find()
.offset(offset ? static_cast<int>(*offset) : -1)
+2 -3
View File
@@ -19,10 +19,9 @@
#pragma once
#include <optional>
#include <vector>
#include <boost/optional.hpp>
#include <Wt/Dbo/Dbo.h>
#include <Wt/WDateTime.h>
@@ -162,7 +161,7 @@ class User : public Wt::Dbo::Dbo<User>
void starRelease(Wt::Dbo::ptr<Release> release);
void unstarRelease(Wt::Dbo::ptr<Release> release);
bool hasStarredRelease(Wt::Dbo::ptr<Release> release) const;
std::vector<Wt::Dbo::ptr<Release>> getStarredReleases(boost::optional<std::size_t> offset = {}, boost::optional<std::size_t> size = {}) const;
std::vector<Wt::Dbo::ptr<Release>> getStarredReleases(std::optional<std::size_t> offset = {}, std::optional<std::size_t> size = {}) const;
void starTrack(Wt::Dbo::ptr<Track> track);
void unstarTrack(Wt::Dbo::ptr<Track> track);
+1 -1
View File
@@ -68,7 +68,7 @@ Image::load(const std::vector<unsigned char>& rawData)
}
bool
Image::load(boost::filesystem::path p)
Image::load(const std::filesystem::path& p)
{
try
{
+2 -3
View File
@@ -19,10 +19,9 @@
#pragma once
#include <filesystem>
#include <vector>
#include <boost/filesystem/path.hpp>
#include <Magick++.h>
namespace Image
@@ -49,7 +48,7 @@ class Image
// input
bool load(const std::vector<unsigned char>& rawData);
bool load(boost::filesystem::path p);
bool load(const std::filesystem::path& p);
Geometry getSize() const;
+8 -9
View File
@@ -17,7 +17,6 @@
* along with LMS. If not, see <http://www.gnu.org/licenses/>.
*/
#include <boost/filesystem.hpp>
#include <boost/property_tree/xml_parser.hpp>
#include <Wt/WServer.h>
@@ -29,6 +28,7 @@
#include "auth/AuthTokenService.hpp"
#include "auth/PasswordService.hpp"
#include "cover/CoverArtGrabber.hpp"
#include "database/Db.hpp"
#include "image/Image.hpp"
#include "scanner/MediaScanner.hpp"
#include "similarity/features/SimilarityFeaturesScannerAddon.hpp"
@@ -42,9 +42,9 @@ std::vector<std::string> generateWtConfig(std::string execPath)
{
std::vector<std::string> args;
const boost::filesystem::path wtConfigPath {getService<Config>()->getPath("working-dir") / "wt_config.xml"};
const boost::filesystem::path wtLogFilePath {getService<Config>()->getPath("log-file", "/var/log/lms.log")};
const boost::filesystem::path wtAccessLogFilePath {getService<Config>()->getPath("access-log-file", "/var/log/lms.access.log")};
const std::filesystem::path wtConfigPath {getService<Config>()->getPath("working-dir") / "wt_config.xml"};
const std::filesystem::path wtLogFilePath {getService<Config>()->getPath("log-file", "/var/log/lms.log")};
const std::filesystem::path wtAccessLogFilePath {getService<Config>()->getPath("access-log-file", "/var/log/lms.access.log")};
args.push_back(execPath);
args.push_back("--config=" + wtConfigPath.string());
@@ -86,7 +86,7 @@ std::vector<std::string> generateWtConfig(std::string execPath)
int main(int argc, char* argv[])
{
boost::filesystem::path configFilePath {"/etc/lms.conf"};
std::filesystem::path configFilePath {"/etc/lms.conf"};
int res = EXIT_FAILURE;
assert(argc > 0);
@@ -110,8 +110,8 @@ int main(int argc, char* argv[])
ServiceProvider<Config>::create(configFilePath);
// Make sure the working directory exists
boost::filesystem::create_directories(getService<Config>()->getPath("working-dir"));
boost::filesystem::create_directories(getService<Config>()->getPath("working-dir") / "cache");
std::filesystem::create_directories(getService<Config>()->getPath("working-dir"));
std::filesystem::create_directories(getService<Config>()->getPath("working-dir") / "cache");
// Construct WT configuration and get the argc/argv back
std::vector<std::string> wtServerArgs = generateWtConfig(argv[0]);
@@ -128,11 +128,10 @@ int main(int argc, char* argv[])
// lib init
Image::init(argv[0]);
Av::AvInit();
Av::Transcoder::init();
// Initializing a connection pool to the database that will be shared along services
Database::Database database {getService<Config>()->getPath("working-dir") / "lms.db"};
Database::Db database {getService<Config>()->getPath("working-dir") / "lms.db"};
UserInterface::LmsApplicationGroupContainer appGroups;
+7 -7
View File
@@ -29,21 +29,21 @@ namespace MetaData
using MetadataMap = std::map<std::string, std::string>;
boost::optional<std::string>
std::optional<std::string>
findFirstValueOf(const MetadataMap& metadataMap, std::initializer_list<std::string> tags)
{
auto it = std::find_first_of(std::cbegin(metadataMap), std::cend(metadataMap), std::cbegin(tags), std::cend(tags), [](const auto& it, const auto& str) { return it.first == str; });
if (it == std::cend(metadataMap))
return boost::none;
return std::nullopt;
return stringTrim(it->second);
}
static
boost::optional<Album>
std::optional<Album>
getAlbum(const MetadataMap& metadataMap)
{
boost::optional<Album> res;
std::optional<Album> res;
auto album {findFirstValueOf(metadataMap, {"ALBUM"})};
if (!album)
@@ -115,8 +115,8 @@ getArtists(const MetadataMap& metadataMap)
return artists;
}
boost::optional<Track>
AvFormat::parse(const boost::filesystem::path& p, bool debug)
std::optional<Track>
AvFormat::parse(const std::filesystem::path& p, bool debug)
{
Track track;
@@ -215,7 +215,7 @@ AvFormat::parse(const boost::filesystem::path& p, bool debug)
}
catch(Av::MediaFileException& e)
{
return boost::none;
return std::nullopt;
}
return track;
+1 -4
View File
@@ -19,9 +19,6 @@
#pragma once
#include <map>
#include <string>
#include "MetaData.hpp"
namespace MetaData
@@ -31,7 +28,7 @@ namespace MetaData
class AvFormat : public Parser
{
public:
boost::optional<Track> parse(const boost::filesystem::path& p, bool debug = false) override;
std::optional<Track> parse(const std::filesystem::path& p, bool debug = false) override;
};
} // namespace MetaData
+10 -11
View File
@@ -20,12 +20,11 @@
#pragma once
#include <chrono>
#include <filesystem>
#include <map>
#include <optional>
#include <set>
#include <boost/optional.hpp>
#include <boost/filesystem.hpp>
namespace MetaData
{
using Clusters = std::map<std::string /* type */, std::set<std::string> /* names */>;
@@ -54,15 +53,15 @@ namespace MetaData
std::string title;
std::string musicBrainzTrackID;
std::string musicBrainzRecordID;
boost::optional<Album> album;
std::optional<Album> album;
Clusters clusters;
std::chrono::milliseconds duration {};
boost::optional<std::size_t> trackNumber;
boost::optional<std::size_t> totalTrack;
boost::optional<std::size_t> discNumber;
boost::optional<std::size_t> totalDisc;
boost::optional<int> year;
boost::optional<int> originalYear;
std::optional<std::size_t> trackNumber;
std::optional<std::size_t> totalTrack;
std::optional<std::size_t> discNumber;
std::optional<std::size_t> totalDisc;
std::optional<int> year;
std::optional<int> originalYear;
bool hasCover {false};
std::vector<AudioStream> audioStreams;
std::string acoustID;
@@ -73,7 +72,7 @@ namespace MetaData
class Parser
{
public:
virtual boost::optional<Track> parse(const boost::filesystem::path& p, bool debug = false) = 0;
virtual std::optional<Track> parse(const std::filesystem::path& p, bool debug = false) = 0;
void setClusterTypeNames(const std::set<std::string>& clusterTypeNames) { _clusterTypeNames = clusterTypeNames; }
+6 -6
View File
@@ -126,10 +126,10 @@ getAlbumArtists(const TagLib::PropertyMap& properties)
}
static
boost::optional<Album>
std::optional<Album>
getAlbum(const TagLib::PropertyMap& properties)
{
boost::optional<Album> res;
std::optional<Album> res;
std::vector<std::string> albumName {getPropertyValues(properties, "ALBUM")};
if (albumName.empty())
@@ -145,8 +145,8 @@ getAlbum(const TagLib::PropertyMap& properties)
return res;
}
boost::optional<Track>
TagLibParser::parse(const boost::filesystem::path& p, bool debug)
std::optional<Track>
TagLibParser::parse(const std::filesystem::path& p, bool debug)
{
TagLib::FileRef f {p.string().c_str(),
true, // read audio properties
@@ -155,13 +155,13 @@ TagLibParser::parse(const boost::filesystem::path& p, bool debug)
if (f.isNull())
{
LMS_LOG(METADATA, ERROR) << "File '" << p.string() << "': parsing failed";
return boost::none;
return std::nullopt;
}
if (!f.audioProperties())
{
LMS_LOG(METADATA, INFO) << "File '" << p.string() << "': no audio properties";
return boost::none;
return std::nullopt;
}
Track track;
+1 -4
View File
@@ -19,9 +19,6 @@
#pragma once
#include <map>
#include <string>
#include "MetaData.hpp"
namespace MetaData
@@ -31,7 +28,7 @@ namespace MetaData
class TagLibParser : public Parser
{
public:
boost::optional<Track> parse(const boost::filesystem::path& p, bool debug = false) override;
std::optional<Track> parse(const std::filesystem::path& p, bool debug = false) override;
};
} // namespace MetaData
+22 -23
View File
@@ -21,7 +21,6 @@
#include <stdexcept>
#include <boost/filesystem.hpp>
#include <boost/asio/placeholders.hpp>
#include <Wt/WLocalDateTime.h>
@@ -63,15 +62,15 @@ getNextFirstOfMonth(Wt::WDate current)
}
bool
isFileSupported(const boost::filesystem::path& file, const std::set<boost::filesystem::path>& extensions)
isFileSupported(const std::filesystem::path& file, const std::set<std::filesystem::path>& extensions)
{
return (extensions.find(file.extension()) != extensions.end());
}
bool
isPathInParentPath(const boost::filesystem::path& path, const boost::filesystem::path& parentPath)
isPathInParentPath(const std::filesystem::path& path, const std::filesystem::path& parentPath)
{
boost::filesystem::path curPath = path;
std::filesystem::path curPath = path;
while (curPath.has_parent_path())
{
@@ -327,25 +326,25 @@ MediaScanner::scheduleNextScan()
void
MediaScanner::countAllFiles(Stats& stats)
{
boost::system::error_code ec;
std::error_code ec;
stats.totalFiles = 0;
boost::filesystem::recursive_directory_iterator itPath {_mediaDirectory, ec};
std::filesystem::recursive_directory_iterator itPath {_mediaDirectory, ec};
if (ec)
{
LMS_LOG(DBUPDATER, ERROR) << "Cannot iterate over '" << _mediaDirectory.string() << "': " << ec.message();
return;
}
boost::filesystem::recursive_directory_iterator itEnd;
std::filesystem::recursive_directory_iterator itEnd;
while (_running && itPath != itEnd)
{
const boost::filesystem::path& path {*itPath};
const std::filesystem::path& path {*itPath};
if (!ec)
{
if (boost::filesystem::is_regular(path) && isFileSupported(path, _fileExtensions))
if (std::filesystem::is_regular_file(path) && isFileSupported(path, _fileExtensions))
stats.totalFiles++;
if (stats.totalFiles % 250 == 0)
@@ -498,11 +497,11 @@ void MediaScanner::notifyInProgressIfNeeded(Stats& stats)
}
void
MediaScanner::scanAudioFile(const boost::filesystem::path& file, bool forceScan, Stats& stats)
MediaScanner::scanAudioFile(const std::filesystem::path& file, bool forceScan, Stats& stats)
{
notifyInProgressIfNeeded(stats);
auto lastWriteTime = Wt::WDateTime::fromTime_t(boost::filesystem::last_write_time(file));
const auto lastWriteTime {Wt::WDateTime::fromTimePoint(std::filesystem::last_write_time(file))};
if (!forceScan)
{
@@ -518,7 +517,7 @@ MediaScanner::scanAudioFile(const boost::filesystem::path& file, bool forceScan,
}
}
boost::optional<MetaData::Track> trackInfo {_metadataParser.parse(file)};
std::optional<MetaData::Track> trackInfo {_metadataParser.parse(file)};
if (!trackInfo)
{
stats.scanErrors++;
@@ -642,11 +641,11 @@ MediaScanner::scanAudioFile(const boost::filesystem::path& file, bool forceScan,
}
void
MediaScanner::scanMediaDirectory(boost::filesystem::path mediaDirectory, bool forceScan, Stats& stats)
MediaScanner::scanMediaDirectory(const std::filesystem::path& mediaDirectory, bool forceScan, Stats& stats)
{
boost::system::error_code ec;
std::error_code ec;
boost::filesystem::recursive_directory_iterator itPath(mediaDirectory, ec);
std::filesystem::recursive_directory_iterator itPath {mediaDirectory, ec};
if (ec)
{
LMS_LOG(DBUPDATER, ERROR) << "Cannot iterate over '" << mediaDirectory.string() << "': " << ec.message();
@@ -654,17 +653,17 @@ MediaScanner::scanMediaDirectory(boost::filesystem::path mediaDirectory, bool fo
return;
}
boost::filesystem::recursive_directory_iterator itEnd;
std::filesystem::recursive_directory_iterator itEnd;
while (_running && itPath != itEnd)
{
const boost::filesystem::path& path {*itPath};
const std::filesystem::path& path {*itPath};
if (ec)
{
LMS_LOG(DBUPDATER, ERROR) << "Cannot process entry '" << path.string() << "': " << ec.message();
stats.scanErrors++;
}
else if (boost::filesystem::is_regular(path))
else if (std::filesystem::is_regular_file(path))
{
if (isFileSupported(path, _fileExtensions))
scanAudioFile(path, forceScan, stats );
@@ -678,14 +677,14 @@ MediaScanner::scanMediaDirectory(boost::filesystem::path mediaDirectory, bool fo
// Check if a file exists and is still in a media directory
static bool
checkFile(const boost::filesystem::path& p, const boost::filesystem::path& mediaDirectory, const std::set<boost::filesystem::path>& extensions)
checkFile(const std::filesystem::path& p, const std::filesystem::path& mediaDirectory, const std::set<std::filesystem::path>& extensions)
{
try
{
// For each track, make sure the the file still exists
// and still belongs to a media directory
if (!boost::filesystem::exists( p )
|| !boost::filesystem::is_regular( p ) )
if (!std::filesystem::exists( p )
|| !std::filesystem::is_regular_file( p ) )
{
LMS_LOG(DBUPDATER, INFO) << "Removing '" << p.string() << "': missing";
return false;
@@ -706,7 +705,7 @@ checkFile(const boost::filesystem::path& p, const boost::filesystem::path& media
return true;
}
catch (boost::filesystem::filesystem_error& e)
catch (std::filesystem::filesystem_error& e)
{
LMS_LOG(DBUPDATER, ERROR) << "Caught exception while checking file '" << p.string() << "': " << e.what();
return false;
@@ -716,7 +715,7 @@ checkFile(const boost::filesystem::path& p, const boost::filesystem::path& media
void
MediaScanner::removeMissingTracks(Stats& stats)
{
std::vector<boost::filesystem::path> trackPaths;
std::vector<std::filesystem::path> trackPaths;
{
auto transaction {_dbSession->createSharedTransaction()};
trackPaths = Track::getAllPaths(*_dbSession);;
+10 -9
View File
@@ -21,6 +21,7 @@
#include <chrono>
#include <mutex>
#include <optional>
#include <Wt/WDateTime.h>
#include <Wt/WIOService.h>
@@ -86,8 +87,8 @@ class MediaScanner
{
State currentState {State::NotScheduled};
Wt::WDateTime nextScheduledScan;
boost::optional<Stats> lastScanStats;
boost::optional<Stats> inProgressStats;
std::optional<Stats> lastScanStats;
std::optional<Stats> inProgressStats;
};
Status getStatus();
@@ -110,7 +111,7 @@ class MediaScanner
// Update database (scheduled callback)
void scan(boost::system::error_code ec);
void scanMediaDirectory( boost::filesystem::path mediaDirectory, bool forceScan, Stats& stats);
void scanMediaDirectory( const std::filesystem::path& mediaDirectory, bool forceScan, Stats& stats);
// Helpers
void refreshScanSettings();
@@ -119,8 +120,8 @@ class MediaScanner
void removeMissingTracks(Stats& stats);
void removeOrphanEntries();
void checkDuplicatedAudioFiles(Stats& stats);
void scanAudioFile(const boost::filesystem::path& file, bool forceScan, Stats& stats);
Database::IdType doScanAudioFile(const boost::filesystem::path& file, Stats& stats);
void scanAudioFile(const std::filesystem::path& file, bool forceScan, Stats& stats);
Database::IdType doScanAudioFile(const std::filesystem::path& file, Stats& stats);
void notifyInProgressIfNeeded(Stats& stats);
void notifyInProgress(Stats& stats);
@@ -137,16 +138,16 @@ class MediaScanner
std::mutex _statusMutex;
State _curState {State::NotScheduled};
boost::optional<Stats> _inProgressStats;
boost::optional<Stats> _lastScanStats;
std::optional<Stats> _inProgressStats;
std::optional<Stats> _lastScanStats;
Wt::WDateTime _nextScheduledScan;
// Current scan settings
std::size_t _scanVersion {};
Wt::WTime _startTime;
Database::ScanSettings::UpdatePeriod _updatePeriod {Database::ScanSettings::UpdatePeriod::Never};
std::set<boost::filesystem::path> _fileExtensions;
boost::filesystem::path _mediaDirectory;
std::set<std::filesystem::path> _fileExtensions;
std::filesystem::path _mediaDirectory;
}; // class MediaScanner
@@ -31,24 +31,24 @@ namespace Similarity {
static
boost::filesystem::path getCacheDirectory()
std::filesystem::path getCacheDirectory()
{
return getService<Config>()->getPath("working-dir") / "cache" / "features";
}
static boost::filesystem::path getCacheNetworkFilePath()
static std::filesystem::path getCacheNetworkFilePath()
{
return getCacheDirectory() / "network";
};
static boost::filesystem::path getCacheTrackPositionsFilePath()
static std::filesystem::path getCacheTrackPositionsFilePath()
{
return getCacheDirectory() / "track_positions";
}
static
bool
networkToCacheFile(const SOM::Network& network, boost::filesystem::path path)
networkToCacheFile(const SOM::Network& network, std::filesystem::path path)
{
try
{
@@ -91,8 +91,8 @@ networkToCacheFile(const SOM::Network& network, boost::filesystem::path path)
}
static
boost::optional<SOM::Network>
createNetworkFromCacheFile(boost::filesystem::path path)
std::optional<SOM::Network>
createNetworkFromCacheFile(std::filesystem::path path)
{
try
{
@@ -137,13 +137,13 @@ createNetworkFromCacheFile(boost::filesystem::path path)
catch (boost::property_tree::ptree_error& error)
{
LMS_LOG(SIMILARITY, ERROR) << "Cannot read network cache: " << error.what();
return boost::none;
return std::nullopt;
}
}
static
bool
objectPositionToCacheFile(const std::map<Database::IdType, std::set<SOM::Position>>& objectsPosition, boost::filesystem::path path)
objectPositionToCacheFile(const std::map<Database::IdType, std::set<SOM::Position>>& objectsPosition, std::filesystem::path path)
{
try
{
@@ -178,8 +178,8 @@ objectPositionToCacheFile(const std::map<Database::IdType, std::set<SOM::Positio
}
static
boost::optional<std::map<Database::IdType, std::set<SOM::Position>>>
createObjectPositionsFromCacheFile(boost::filesystem::path path)
std::optional<std::map<Database::IdType, std::set<SOM::Position>>>
createObjectPositionsFromCacheFile(std::filesystem::path path)
{
try
{
@@ -210,21 +210,21 @@ createObjectPositionsFromCacheFile(boost::filesystem::path path)
catch (boost::property_tree::ptree_error& error)
{
LMS_LOG(SIMILARITY, ERROR) << "Cannot create object position from cache file: " << error.what();
return boost::none;
return std::nullopt;
}
}
void
FeaturesCache::invalidate()
{
boost::filesystem::remove(getCacheNetworkFilePath());
boost::filesystem::remove(getCacheTrackPositionsFilePath());
std::filesystem::remove(getCacheNetworkFilePath());
std::filesystem::remove(getCacheTrackPositionsFilePath());
}
boost::optional<FeaturesCache>
std::optional<FeaturesCache>
FeaturesCache::read()
{
boost::optional<FeaturesCache> res;
std::optional<FeaturesCache> res;
auto network{createNetworkFromCacheFile(getCacheNetworkFilePath())};
if (!network)
@@ -240,7 +240,7 @@ FeaturesCache::read()
void
FeaturesCache::write()
{
boost::filesystem::create_directories(getService<Config>()->getPath("working-dir") / "cache" / "features");
std::filesystem::create_directories(getService<Config>()->getPath("working-dir") / "cache" / "features");
if (!networkToCacheFile(_network, getCacheNetworkFilePath())
|| !objectPositionToCacheFile(_trackPositions, getCacheTrackPositionsFilePath()))
@@ -250,8 +250,8 @@ FeaturesCache::write()
}
FeaturesCache::FeaturesCache(SOM::Network network, ObjectPositions trackPositions)
: _network{std::move(network)},
_trackPositions{std::move(trackPositions)}
: _network {std::move(network)},
_trackPositions {std::move(trackPositions)}
{
}
@@ -20,6 +20,7 @@
#pragma once
#include <map>
#include <optional>
#include <set>
#include "database/Types.hpp"
@@ -33,7 +34,7 @@ class FeaturesCache
static void invalidate();
static boost::optional<FeaturesCache> read();
static std::optional<FeaturesCache> read();
void write();
private:
@@ -56,7 +56,7 @@ getTracksWithMBIDAndMissingFeatures(Database::Session& dbSession)
FeaturesScannerAddon::FeaturesScannerAddon(std::unique_ptr<Database::Session> dbSession)
: _dbSession {std::move(dbSession)}
{
boost::optional<Similarity::FeaturesCache> cache {Similarity::FeaturesCache::read()};
std::optional<Similarity::FeaturesCache> cache {Similarity::FeaturesCache::read()};
if (cache)
{
auto searcher {std::make_shared<Similarity::FeaturesSearcher>(*_dbSession.get(), *cache, [&]() { return _stopRequested; })};
@@ -40,8 +40,8 @@ class FeaturesScannerAddon final : public Scanner::MediaScannerAddon
void requestStop() override;
void preScanComplete() override;
void trackAdded(Database::IdType trackId) override {}
void trackToRemove(Database::IdType trackId) override {}
void trackAdded(Database::IdType) override {}
void trackToRemove(Database::IdType) override {}
void trackUpdated(Database::IdType trackId) override;
bool fetchFeatures(Database::IdType trackId, const std::string& MBID);
@@ -68,10 +68,10 @@ getFeatureInfoMapNbDimensions(const FeatureInfoMap& featureInfoMap)
}
static
boost::optional<SOM::InputVector>
std::optional<SOM::InputVector>
getInputVectorFromTrack(Database::Session& session, Database::IdType trackId, const FeatureInfoMap& featuresInfo, std::size_t nbDimensions)
{
boost::optional<SOM::InputVector> res {SOM::InputVector {nbDimensions}};
std::optional<SOM::InputVector> res {SOM::InputVector {nbDimensions}};
std::map<std::string, std::vector<double>> features;
for (auto itFeatureInfo : featuresInfo)
@@ -150,7 +150,7 @@ FeaturesSearcher::FeaturesSearcher(Database::Session& session, std::function<boo
if (stopRequested())
return;
boost::optional<SOM::InputVector> inputVector {getInputVectorFromTrack(session, trackId, featuresInfo, nbDimensions)};
std::optional<SOM::InputVector> inputVector {getInputVectorFromTrack(session, trackId, featuresInfo, nbDimensions)};
if (!inputVector)
continue;
@@ -456,7 +456,7 @@ FeaturesSearcher::getSimilarObjects(const std::set<Database::IdType>& ids,
break;
// If there is not enough objects, try again with closest neighbour until there is too much distance
boost::optional<SOM::Position> closestRefVectorPosition {_network->getClosestRefVectorPosition(searchedRefVectorsPosition, _networkRefVectorsDistanceMedian * 0.75)};
std::optional<SOM::Position> closestRefVectorPosition {_network->getClosestRefVectorPosition(searchedRefVectorsPosition, _networkRefVectorsDistanceMedian * 0.75)};
if (!closestRefVectorPosition)
break;
+6 -6
View File
@@ -189,10 +189,10 @@ Network::getClosestRefVectorPosition(const InputVector& data) const
});
}
boost::optional<Position>
std::optional<Position>
Network::getClosestRefVectorPosition(const InputVector& data, InputVector::Distance maxDistance) const
{
boost::optional<Position> position {getClosestRefVectorPosition(data)};
std::optional<Position> position {getClosestRefVectorPosition(data)};
if (_distanceFunc(data, _refVectors.get(*position), _weights) > maxDistance)
position.reset();
@@ -200,7 +200,7 @@ Network::getClosestRefVectorPosition(const InputVector& data, InputVector::Dista
return position;
}
boost::optional<Position>
std::optional<Position>
Network::getClosestRefVectorPosition(const std::set<Position>& refVectorsPosition, InputVector::Distance maxDistance) const
{
std::set<Position> neighboursPosition;
@@ -221,7 +221,7 @@ Network::getClosestRefVectorPosition(const std::set<Position>& refVectorsPositio
neighboursPosition.erase(refVectorPosition);
if (neighboursPosition.empty())
return boost::none;
return std::nullopt;
// Now compute the distance for each neighbour
struct NeighbourInfo
@@ -247,9 +247,9 @@ Network::getClosestRefVectorPosition(const std::set<Position>& refVectorsPositio
}
if (neighboursInfo.empty())
return boost::none;
return std::nullopt;
auto min {std::min_element(neighboursInfo.begin(), neighboursInfo.end(),
auto min {std::min_element(std::cbegin(neighboursInfo), std::cend(neighboursInfo),
[&](const auto& a, const auto& b)
{
return a.distance < b.distance;
+3 -4
View File
@@ -21,11 +21,10 @@
#include <vector>
#include <set>
#include <optional>
#include <ostream>
#include <functional>
#include <boost/optional.hpp>
#include "utils/Exception.hpp"
#include "InputVector.hpp"
#include "Matrix.hpp"
@@ -70,9 +69,9 @@ class Network
const InputVector& getRefVector(const Position& position) const;
Position getClosestRefVectorPosition(const InputVector& data) const;
boost::optional<Position> getClosestRefVectorPosition(const InputVector& data, InputVector::Distance maxDistance) const;
std::optional<Position> getClosestRefVectorPosition(const InputVector& data, InputVector::Distance maxDistance) const;
boost::optional<Position> getClosestRefVectorPosition(const std::set<Position>& refVectorsPosition, InputVector::Distance maxDistance) const;
std::optional<Position> getClosestRefVectorPosition(const std::set<Position>& refVectorsPosition, InputVector::Distance maxDistance) const;
InputVector::Distance getRefVectorsDistance(const Position& position1, const Position& position2) const;
+5 -6
View File
@@ -54,12 +54,12 @@ createAuthToken(Database::IdType userId, const Wt::WDateTime& expiry)
}
boost::optional<Database::IdType>
std::optional<Database::IdType>
processAuthToken(const Wt::WEnvironment& env)
{
const std::string* authCookie {env.getCookie(authCookieName)};
if (!authCookie)
return boost::none;
return std::nullopt;
const auto res {getService<::Auth::AuthTokenService>()->processAuthToken(LmsApp->getDbSession(), boost::asio::ip::address::from_string(env.clientAddress()), *authCookie)};
switch (res.state)
@@ -67,7 +67,7 @@ processAuthToken(const Wt::WEnvironment& env)
case ::Auth::AuthTokenService::AuthTokenProcessResult::State::NotFound:
case ::Auth::AuthTokenService::AuthTokenProcessResult::State::Throttled:
LmsApp->setCookie(authCookieName, std::string {}, 0, "", "", env.urlScheme() == "https");
return boost::none;
return std::nullopt;
case ::Auth::AuthTokenService::AuthTokenProcessResult::State::Found:
createAuthToken(res.authTokenInfo->userId, res.authTokenInfo->expiry);
@@ -107,7 +107,6 @@ class AuthModel : public Wt::WFormModel
user.modify()->setLastLogin(Wt::WDateTime::currentDateTime());
_userId = user.id();
const Wt::WDateTime now {Wt::WDateTime::currentDateTime()};
isDemo = user->isDemo();
}
@@ -151,11 +150,11 @@ class AuthModel : public Wt::WFormModel
return (validation(field).state() == Wt::ValidationState::Valid);
}
boost::optional<Database::IdType> getUserId() const { return _userId; }
std::optional<Database::IdType> getUserId() const { return _userId; }
private:
boost::optional<Database::IdType> _userId;
std::optional<Database::IdType> _userId;
};
const AuthModel::Field AuthModel::LoginNameField {"login-name"};
+1 -3
View File
@@ -19,15 +19,13 @@
#pragma once
#include <boost/optional.hpp>
#include <Wt/WTemplateFormView.h>
#include "database/Types.hpp"
namespace UserInterface {
boost::optional<Database::IdType>
std::optional<Database::IdType>
processAuthToken(const Wt::WEnvironment& env);
class Auth : public Wt::WTemplateFormView
+7 -6
View File
@@ -33,6 +33,7 @@
#include "cover/CoverArtGrabber.hpp"
#include "database/Artist.hpp"
#include "database/Cluster.hpp"
#include "database/Db.hpp"
#include "database/Release.hpp"
#include "database/User.hpp"
#include "explore/Explore.hpp"
@@ -56,7 +57,7 @@
namespace UserInterface {
std::unique_ptr<Wt::WApplication>
LmsApplication::create(const Wt::WEnvironment& env, Database::Database& db, LmsApplicationGroupContainer& appGroups)
LmsApplication::create(const Wt::WEnvironment& env, Database::Db& db, LmsApplicationGroupContainer& appGroups)
{
return std::make_unique<LmsApplication>(env, db.createSession(), appGroups);
}
@@ -496,13 +497,13 @@ LmsApplication::createHome()
playqueue->playNext();
});
playqueue->loadTrack.connect([=] (Database::IdType trackId, bool play)
playqueue->trackSelected.connect([=] (Database::IdType trackId, bool play)
{
_events.lastLoadedTrackId = trackId;
_events.trackLoaded(trackId, play);
});
playqueue->trackUnload.connect([=]
playqueue->trackUnselected.connect([=]
{
_events.lastLoadedTrackId.reset();
_events.trackUnloaded();
@@ -555,7 +556,7 @@ LmsApplication::createHome()
});
// Events from Application group
_events.appOpen.connect([=] (LmsApplicationInfo info)
_events.appOpen.connect([=] (LmsApplicationInfo)
{
// Only one active session by user
if (!LmsApp->isUserDemo())
@@ -565,10 +566,10 @@ LmsApplication::createHome()
}
});
internalPathChanged().connect(std::bind([=]
internalPathChanged().connect([=]
{
handlePathChange(mainStack, isUserAdmin());
}));
});
handlePathChange(mainStack, isUserAdmin());
}
+7 -10
View File
@@ -17,14 +17,12 @@
* along with LMS. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef LMS_APPLICATION_HPP
#define LMS_APPLICATION_HPP
#pragma once
#include <boost/optional.hpp>
#include <optional>
#include <Wt/WApplication.h>
#include "database/Database.hpp"
#include "scanner/MediaScanner.hpp"
#include "LmsApplicationGroup.hpp"
@@ -32,6 +30,7 @@
namespace Database {
class Artist;
class Cluster;
class Db;
class Release;
class User;
}
@@ -51,7 +50,7 @@ struct Events
// A track is being loaded
Wt::Signal<Database::IdType /* trackId */, bool /* play */> trackLoaded;
boost::optional<Database::IdType> lastLoadedTrackId;
std::optional<Database::IdType> lastLoadedTrackId;
// Unload current track
Wt::Signal<> trackUnloaded;
@@ -75,7 +74,7 @@ class LmsApplication : public Wt::WApplication
public:
LmsApplication(const Wt::WEnvironment& env, std::unique_ptr<Database::Session> dbSession, LmsApplicationGroupContainer& appGroups);
static std::unique_ptr<Wt::WApplication> create(const Wt::WEnvironment& env, Database::Database& db, LmsApplicationGroupContainer& appGroups);
static std::unique_ptr<Wt::WApplication> create(const Wt::WEnvironment& env, Database::Db& db, LmsApplicationGroupContainer& appGroups);
static LmsApplication* instance();
// Session application data
@@ -124,8 +123,8 @@ class LmsApplication : public Wt::WApplication
std::unique_ptr<Database::Session> _dbSession;
LmsApplicationGroupContainer& _appGroups;
Events _events;
boost::optional<Database::IdType> _userId;
boost::optional<bool> _userAuthStrong;
std::optional<Database::IdType> _userId;
std::optional<bool> _userAuthStrong;
std::shared_ptr<ImageResource> _imageResource;
std::shared_ptr<AudioResource> _audioResource;
};
@@ -136,5 +135,3 @@ class LmsApplication : public Wt::WApplication
} // namespace UserInterface
#endif
+1 -1
View File
@@ -30,7 +30,7 @@ namespace UserInterface {
LmsApplicationInfo
LmsApplicationInfo::fromEnvironment(const Wt::WEnvironment& env)
{
LmsApplicationInfo info = {.userAgent = wApp->environment().agent()};
LmsApplicationInfo info = {.userAgent = env.agent()};
return info;
}
+9 -9
View File
@@ -139,7 +139,7 @@ PlayQueue::PlayQueue()
trackPos = LmsApp->getUser()->getCurPlayingTrackPos();
}
load(trackPos, false);
loadTrack(trackPos, false);
});
trackList = LmsApp->getUser()->getQueuedTrackList(LmsApp->getDbSession());
}
@@ -192,11 +192,11 @@ PlayQueue::stop()
{
updateCurrentTrack(false);
_trackPos.reset();
trackUnload.emit();
trackUnselected.emit();
}
void
PlayQueue::load(std::size_t pos, bool play)
PlayQueue::loadTrack(std::size_t pos, bool play)
{
updateCurrentTrack(false);
@@ -237,7 +237,7 @@ PlayQueue::load(std::size_t pos, bool play)
updateCurrentTrack(true);
loadTrack.emit(trackId, play);
trackSelected.emit(trackId, play);
}
void
@@ -249,7 +249,7 @@ PlayQueue::playPrevious()
if (*_trackPos == 0)
stop();
else
load(*_trackPos - 1, true);
loadTrack(*_trackPos - 1, true);
}
void
@@ -257,11 +257,11 @@ PlayQueue::playNext()
{
if (!_trackPos)
{
load(0, true);
loadTrack(0, true);
return;
}
load(*_trackPos + 1, true);
loadTrack(*_trackPos + 1, true);
}
void
@@ -327,7 +327,7 @@ PlayQueue::playTracks(const std::vector<Database::IdType>& trackIds)
{
clearTracks();
enqueueTracks(trackIds);
load(0, true);
loadTrack(0, true);
LmsApp->notifyMsg(MsgType::Info, Wt::WString::trn("Lms.PlayQueue.nb-tracks-playing", trackIds.size()).arg(trackIds.size()), std::chrono::milliseconds(2000));
}
@@ -377,7 +377,7 @@ PlayQueue::addSome()
{
auto pos = _entriesContainer->indexOf(entry);
if (pos >= 0)
load(pos, true);
loadTrack(pos, true);
}));
Wt::WText* delBtn = entry->bindNew<Wt::WText>("del-btn", Wt::WString::tr("Lms.PlayQueue.template.delete-btn"), Wt::TextFormat::XHTML);
+7 -7
View File
@@ -19,13 +19,13 @@
#pragma once
#include <optional>
#include <Wt/WContainerWidget.h>
#include <Wt/WPushButton.h>
#include <Wt/WTemplate.h>
#include <Wt/WText.h>
#include <boost/optional.hpp>
#include "database/Types.hpp"
namespace Similarity {
@@ -53,10 +53,10 @@ class PlayQueue : public Wt::WTemplate
void playPrevious();
// Signal emitted when a track is to be load(and optionally played)
Wt::Signal<Database::IdType /*trackId*/, bool /*play*/> loadTrack;
Wt::Signal<Database::IdType /*trackId*/, bool /*play*/> trackSelected;
// Signal emitted when play has to be stopped
Wt::Signal<> trackUnload;
// Signal emitted when track is unselected (has to be stopped)
Wt::Signal<> trackUnselected;
private:
Wt::Dbo::ptr<Database::TrackList> getTrackList();
@@ -71,7 +71,7 @@ class PlayQueue : public Wt::WTemplate
void updateRepeatBtn();
void updateRadioBtn();
void load(std::size_t pos, bool play);
void loadTrack(std::size_t pos, bool play);
void stop();
void addRadioTrackFromSimilarity(std::shared_ptr<Similarity::Finder> similarityFinder);
@@ -85,7 +85,7 @@ class PlayQueue : public Wt::WTemplate
Wt::WText* _nbTracks {};
Wt::WText* _repeatBtn {};
Wt::WText* _radioBtn {};
boost::optional<std::size_t> _trackPos; // current track position, if set
std::optional<std::size_t> _trackPos; // current track position, if set
};
} // namespace UserInterface
+3 -3
View File
@@ -53,7 +53,7 @@ class UserModel : public Wt::WFormModel
static const Field AudioTranscodeBitrateLimitField;
static const Field DemoField;
UserModel(boost::optional<Database::IdType> userId)
UserModel(std::optional<Database::IdType> userId)
: Wt::WFormModel(),
_userId(userId)
{
@@ -80,7 +80,7 @@ class UserModel : public Wt::WFormModel
void saveData()
{
boost::optional<Database::User::PasswordHash> passwordHash;
std::optional<Database::User::PasswordHash> passwordHash;
if (!valueText(PasswordField).empty())
passwordHash = getService<::Auth::PasswordService>()->hashPassword(valueText(PasswordField).toUTF8());
@@ -203,7 +203,7 @@ class UserModel : public Wt::WFormModel
}
std::shared_ptr<ValueStringModel<Bitrate>> _bitrateModel;
boost::optional<Database::IdType> _userId;
std::optional<Database::IdType> _userId;
};
const Wt::WFormModel::Field UserModel::LoginField = "login";
+4 -4
View File
@@ -19,7 +19,7 @@
#include "Validators.hpp"
#include <boost/filesystem.hpp>
#include <filesystem>
#include <Wt/WLengthValidator.h>
@@ -53,11 +53,11 @@ DirectoryValidator::validate(const Wt::WString& input) const
if (input.empty())
return Wt::WValidator::validate(input);
boost::filesystem::path p(input.toUTF8());
boost::system::error_code ec;
const std::filesystem::path p {input.toUTF8()};
std::error_code ec;
// TODO check rights
bool res = boost::filesystem::is_directory(p, ec);
bool res = std::filesystem::is_directory(p, ec);
if (ec)
return Wt::WValidator::Result(Wt::ValidationState::Invalid, ec.message()); // TODO translate common errors
else if (res)
+6 -5
View File
@@ -20,7 +20,8 @@
#pragma once
#include <boost/optional.hpp>
#include <optional>
#include <Wt/WStringListModel.h>
namespace UserInterface {
@@ -41,7 +42,7 @@ class ValueStringModel : public Wt::WStringListModel
return Wt::cpp17::any_cast<Wt::WString>(data(index(static_cast<int>(row), 0), Wt::ItemDataRole::Display));
}
boost::optional<std::size_t>
std::optional<std::size_t>
getRowFromString(const Wt::WString& value)
{
for (std::size_t i{}; i < static_cast<std::size_t>(rowCount()); ++i)
@@ -50,10 +51,10 @@ class ValueStringModel : public Wt::WStringListModel
return i;
}
return boost::none;
return std::nullopt;
}
boost::optional<std::size_t>
std::optional<std::size_t>
getRowFromValue(const T& value)
{
for (std::size_t i{}; i < static_cast<std::size_t>(rowCount()); ++i)
@@ -62,7 +63,7 @@ class ValueStringModel : public Wt::WStringListModel
return i;
}
return boost::none;
return std::nullopt;
}
void
+10 -10
View File
@@ -42,16 +42,16 @@ namespace UserInterface {
Artist::Artist(Filters* filters)
: _filters(filters)
{
wApp->internalPathChanged().connect(std::bind([=]
wApp->internalPathChanged().connect([=]
{
refresh();
}));
});
refresh();
filters->updated().connect(std::bind([=] {
filters->updated().connect([=] {
refresh();
}));
});
}
void
@@ -162,13 +162,13 @@ Artist::refresh()
entry->bindWidget("artist", LmsApplication::createArtistAnchor(artists.front()));
}
boost::optional<int> year = release->getReleaseYear();
std::optional<int> year {release->getReleaseYear()};
if (year)
{
entry->setCondition("if-has-year", true);
entry->bindInt("year", *year);
boost::optional<int> originalYear = release->getReleaseYear(true);
std::optional<int> originalYear {release->getReleaseYear(true)};
if (originalYear && *originalYear != *year)
{
entry->setCondition("if-has-orig-year", true);
@@ -177,16 +177,16 @@ Artist::refresh()
}
Wt::WText* playBtn = entry->bindNew<Wt::WText>("play-btn", Wt::WString::tr("Lms.Explore.template.play-btn"), Wt::TextFormat::XHTML);
playBtn->clicked().connect(std::bind([=]
playBtn->clicked().connect([=]
{
releasesPlay.emit({releaseId});
}));
});
Wt::WText* addBtn = entry->bindNew<Wt::WText>("add-btn", Wt::WString::tr("Lms.Explore.template.add-btn"), Wt::TextFormat::XHTML);
addBtn->clicked().connect(std::bind([=]
addBtn->clicked().connect([=]
{
releasesAdd.emit({releaseId});
}));
});
}
}
+2 -2
View File
@@ -76,8 +76,8 @@ ReleaseInfo::refresh()
if (!release)
return;
boost::optional<std::string> copyright {release->getCopyright()};
boost::optional<std::string> copyrightURL {release->getCopyrightURL()};
std::optional<std::string> copyright {release->getCopyright()};
std::optional<std::string> copyrightURL {release->getCopyrightURL()};
setCondition("if-has-copyright-or-copyright-url", copyright || copyrightURL);
+2 -2
View File
@@ -81,13 +81,13 @@ Release::refresh()
t->bindString("name", Wt::WString::fromUTF8(release->getName()), Wt::TextFormat::Plain);
boost::optional<int> year {release->getReleaseYear()};
std::optional<int> year {release->getReleaseYear()};
if (year)
{
t->setCondition("if-has-year", true);
t->bindInt("year", *year);
boost::optional<int> originalYear {release->getReleaseYear(true)};
std::optional<int> originalYear {release->getReleaseYear(true)};
if (originalYear && *originalYear != *year)
{
t->setCondition("if-has-orig-year", true);
+1 -1
View File
@@ -135,7 +135,7 @@ Releases::addSome()
}
std::vector<Database::IdType>
Releases::getReleases(boost::optional<std::size_t> offset, boost::optional<std::size_t> limit, bool& moreResults) const
Releases::getReleases(std::optional<std::size_t> offset, std::optional<std::size_t> limit, bool& moreResults) const
{
const auto searchKeywords {splitString(_search->text().toUTF8(), " ")};
+2 -2
View File
@@ -19,7 +19,7 @@
#pragma once
#include <boost/optional.hpp>
#include <optional>
#include <Wt/WContainerWidget.h>
#include <Wt/WLineEdit.h>
@@ -44,7 +44,7 @@ class Releases : public Wt::WTemplate
void refresh();
void addSome();
std::vector<Database::IdType> getReleases(boost::optional<std::size_t> offset, boost::optional<std::size_t> limit, bool& moreResults) const;
std::vector<Database::IdType> getReleases(std::optional<std::size_t> offset, std::optional<std::size_t> limit, bool& moreResults) const;
std::vector<Database::IdType> getReleases() const;
Filters* _filters;
+7 -7
View File
@@ -40,8 +40,8 @@ using namespace Database;
namespace UserInterface {
Tracks::Tracks(Filters* filters)
: Wt::WTemplate(Wt::WString::tr("Lms.Explore.Tracks.template")),
_filters(filters)
: Wt::WTemplate {Wt::WString::tr("Lms.Explore.Tracks.template")},
_filters {filters}
{
addFunction("tr", &Wt::WTemplate::Functions::tr);
@@ -56,18 +56,18 @@ _filters(filters)
});
Wt::WText* addBtn = bindNew<Wt::WText>("add-btn", Wt::WString::tr("Lms.Explore.template.add-btn"), Wt::TextFormat::XHTML);
addBtn->clicked().connect(std::bind([=]
addBtn->clicked().connect([=]
{
tracksAdd.emit(getTracks());
}));
});
_tracksContainer = bindNew<Wt::WContainerWidget>("tracks");
_showMore = bindNew<Wt::WPushButton>("show-more", Wt::WString::tr("Lms.Explore.show-more"));
_showMore->clicked().connect(std::bind([=]
_showMore->clicked().connect([=]
{
addSome();
}));
});
refresh();
@@ -75,7 +75,7 @@ _filters(filters)
}
std::vector<Database::IdType>
Tracks::getTracks(boost::optional<std::size_t> offset, boost::optional<std::size_t> size, bool& moreResults)
Tracks::getTracks(std::optional<std::size_t> offset, std::optional<std::size_t> size, bool& moreResults)
{
const auto searchKeywords {splitString(_search->text().toUTF8(), " ")};
const auto clusterIds {_filters->getClusterIds()};
+2 -2
View File
@@ -19,7 +19,7 @@
#pragma once
#include <boost/optional.hpp>
#include <optional>
#include <Wt/WContainerWidget.h>
#include <Wt/WLineEdit.h>
@@ -43,7 +43,7 @@ class Tracks : public Wt::WTemplate
void refresh();
void addSome();
std::vector<Database::IdType> getTracks(boost::optional<std::size_t> offset, boost::optional<std::size_t> size, bool& moreResults);
std::vector<Database::IdType> getTracks(std::optional<std::size_t> offset, std::optional<std::size_t> size, bool& moreResults);
std::vector<Database::IdType> getTracks();
Wt::WContainerWidget* _tracksContainer;
+5 -7
View File
@@ -19,12 +19,10 @@
#include "Config.hpp"
#include <sstream>
#include "utils/Logger.hpp"
Config::Config(const boost::filesystem::path& p)
Config::Config(const std::filesystem::path& p)
{
_config.readFile(p.string().c_str());
}
@@ -35,7 +33,7 @@ Config::getString(const std::string& setting, const std::string& def, const std:
try {
std::string res {(const char*)_config.lookup(setting)};
if (!allowedValues.empty() && allowedValues.find(res) == allowedValues.end())
if (!allowedValues.empty() && allowedValues.find(res) == std::cend(allowedValues))
{
LMS_LOG(MAIN, ERROR) << "Invalid setting for '" << setting << "', using default value '" << def << "'";
return def;
@@ -49,12 +47,12 @@ Config::getString(const std::string& setting, const std::string& def, const std:
}
}
boost::filesystem::path
Config::getPath(const std::string& setting, const boost::filesystem::path& path)
std::filesystem::path
Config::getPath(const std::string& setting, const std::filesystem::path& path)
{
try {
const char* res = _config.lookup(setting);
return boost::filesystem::path(std::string(res));
return std::filesystem::path {std::string(res)};
}
catch (std::exception &e)
{
+3 -3
View File
@@ -18,16 +18,16 @@
*/
#pragma once
#include <filesystem>
#include <set>
#include <boost/filesystem.hpp>
#include <libconfig.h++>
// Used to get config values from configuration files
class Config final
{
public:
Config(const boost::filesystem::path& p);
Config(const std::filesystem::path& p);
~Config() = default;
Config(const Config&) = delete;
@@ -37,7 +37,7 @@ class Config final
// Default values are returned in case of setting not found
std::string getString(const std::string& setting, const std::string& def = "", const std::set<std::string>& allowedValues = {});
boost::filesystem::path getPath(const std::string& setting, const boost::filesystem::path& def = boost::filesystem::path());
std::filesystem::path getPath(const std::string& setting, const std::filesystem::path& def = std::filesystem::path());
unsigned long getULong(const std::string& setting, unsigned long def = 0);
long getLong(const std::string& setting, long def = 0);
bool getBool(const std::string& setting, bool def = false);
+7 -7
View File
@@ -28,7 +28,7 @@
#include "utils/Exception.hpp"
#include "utils/Logger.hpp"
boost::filesystem::path searchExecPath(std::string filename)
std::filesystem::path searchExecPath(std::string filename)
{
std::string path;
@@ -42,7 +42,7 @@ boost::filesystem::path searchExecPath(std::string filename)
tokenizer tok(path, sep);
for (tokenizer::iterator it = tok.begin(); it != tok.end(); ++it)
{
boost::filesystem::path p = *it;
std::filesystem::path p = *it;
p /= filename;
if (!::access(p.c_str(), X_OK))
{
@@ -53,7 +53,7 @@ boost::filesystem::path searchExecPath(std::string filename)
return result;
}
void computeCrc(const boost::filesystem::path& p, std::vector<unsigned char>& crc)
void computeCrc(const std::filesystem::path& p, std::vector<unsigned char>& crc)
{
using crc_type = boost::crc_32_type;
crc_type result;
@@ -87,11 +87,11 @@ void computeCrc(const boost::filesystem::path& p, std::vector<unsigned char>& cr
}
}
bool ensureDirectory(boost::filesystem::path dir)
bool ensureDirectory(const std::filesystem::path& dir)
{
if (boost::filesystem::exists(dir))
return boost::filesystem::is_directory(dir);
if (std::filesystem::exists(dir))
return std::filesystem::is_directory(dir);
else
return boost::filesystem::create_directory(dir);
return std::filesystem::create_directory(dir);
}
+4 -4
View File
@@ -19,15 +19,15 @@
#pragma once
#include <filesystem>
#include <string>
#include <vector>
#include <boost/filesystem.hpp>
boost::filesystem::path searchExecPath(std::string filename);
std::filesystem::path searchExecPath(std::string filename);
void computeCrc(const boost::filesystem::path& p, std::vector<unsigned char>& checksum);
void computeCrc(const std::filesystem::path& p, std::vector<unsigned char>& checksum);
// Make sure the given path is a directory
// Create it if needed
bool ensureDirectory(boost::filesystem::path dir);
bool ensureDirectory(const std::filesystem::path& dir);
+3 -3
View File
@@ -55,7 +55,7 @@ bool readList(const std::string& str, const std::string& separators, std::list<s
}
template<>
boost::optional<std::string>
std::optional<std::string>
readAs(const std::string& str)
{
return str;
@@ -137,13 +137,13 @@ stringEndsWith(const std::string& str, const std::string& ending)
return boost::algorithm::ends_with(str, ending);
}
boost::optional<std::string>
std::optional<std::string>
stringFromHex(const std::string& str)
{
static const char lut[] {"0123456789ABCDEF"};
if (str.length() % 2 != 0)
return boost::none;
return std::nullopt;
std::string res;
res.reserve(str.length() / 2);
+5 -6
View File
@@ -22,13 +22,12 @@
#include <chrono>
#include <list>
#include <map>
#include <optional>
#include <random>
#include <string>
#include <sstream>
#include <vector>
#include <boost/optional.hpp>
#include <Wt/WDate.h>
bool
@@ -53,14 +52,14 @@ std::string
bufferToString(const std::vector<unsigned char>& data);
template<typename T>
boost::optional<T> readAs(const std::string& str)
std::optional<T> readAs(const std::string& str)
{
T res;
std::istringstream iss ( str );
iss >> res;
if (iss.fail())
return boost::none;
return std::nullopt;
return res;
}
@@ -71,7 +70,7 @@ replaceInString(const std::string& str, const std::string& from, const std::stri
bool
stringEndsWith(const std::string& str, const std::string& ending);
boost::optional<std::string>
std::optional<std::string>
stringFromHex(const std::string& str);
// warning: not efficient
@@ -105,7 +104,7 @@ void uniqueAndSortedByOccurence(In first, In last, Out out)
}
template<class T, class Compare = std::less<>>
constexpr const T& clamp( T v, T lo, T hi, Compare comp = {})
constexpr T clamp(T v, T lo, T hi, Compare comp = {})
{
assert(!comp(hi, lo));
return comp(v, lo) ? lo : comp(hi, v) ? hi : v;
+3 -3
View File
@@ -8,14 +8,14 @@ som_SOURCES = \
$(top_srcdir)/src/similarity/features/som/DataNormalizer.cpp \
$(top_srcdir)/src/similarity/features/som/Network.cpp
som_CXXFLAGS=-std=c++14 -Wall -I${top_srcdir}/src/ -I${top_srcdir}/src/similarity/features/som/
som_CXXFLAGS=-std=c++17 -I${top_srcdir}/src/ -I${top_srcdir}/src/similarity/features/som/
database_SOURCES = \
$(srcdir)/database/DatabaseTest.cpp \
$(top_srcdir)/src/database/Artist.cpp \
$(top_srcdir)/src/database/Cluster.cpp \
$(top_srcdir)/src/database/Database.cpp \
$(top_srcdir)/src/database/Db.cpp \
$(top_srcdir)/src/database/TrackArtistLink.cpp \
$(top_srcdir)/src/database/TrackFeatures.cpp \
$(top_srcdir)/src/database/TrackList.cpp \
@@ -29,5 +29,5 @@ database_SOURCES = \
$(top_srcdir)/src/utils/Logger.cpp \
$(top_srcdir)/src/utils/Utils.cpp
database_CXXFLAGS=-std=c++14 -Wall -I${top_srcdir}/src/
database_CXXFLAGS=-std=c++17 -I${top_srcdir}/src/
+8 -8
View File
@@ -19,11 +19,11 @@
#include <cstdlib>
#include <boost/filesystem.hpp>
#include <filesystem>
#include "database/Artist.hpp"
#include "database/Cluster.hpp"
#include "database/Database.hpp"
#include "database/Db.hpp"
#include "database/TrackList.hpp"
#include "database/Release.hpp"
#include "database/Track.hpp"
@@ -34,10 +34,10 @@ using namespace Database;
class ScopedFileDeleter final
{
public:
ScopedFileDeleter(const boost::filesystem::path& path) : _path {path} {}
~ScopedFileDeleter() { boost::filesystem::remove(_path); }
ScopedFileDeleter(const std::filesystem::path& path) : _path {path} {}
~ScopedFileDeleter() { std::filesystem::remove(_path); }
private:
boost::filesystem::path _path;
std::filesystem::path _path;
};
#define CHECK(PRED) \
@@ -1247,19 +1247,19 @@ testDatabaseEmpty(Session& session)
CHECK(Track::getAll(session).empty());
}
int main(int argc, char* argv[])
int main()
{
try
{
const boost::filesystem::path tmpFile {boost::filesystem::temp_directory_path() / boost::filesystem::unique_path()};
const std::filesystem::path tmpFile {std::tmpnam(nullptr)};
ScopedFileDeleter tmpFileDeleter {tmpFile};
std::cout << "Database test file: '" << tmpFile.string() << "'" << std::endl;
for (std::size_t i = 0; i < 2; ++i)
{
Database::Database db {tmpFile};
Database::Db db {tmpFile};
std::unique_ptr<Session> session {db.createSession()};
auto runTest = [&session](const std::string& name, std::function<void(Session&)> testFunc)
+1 -1
View File
@@ -26,7 +26,7 @@
using namespace SOM;
int main(int argc, char* argv[])
int main()
{
static const InputVector::value_type EPSILON = 0.01;
{
+4 -5
View File
@@ -1,4 +1,5 @@
#include <chrono>
#include <optional>
#include <stdexcept>
#include <stdlib.h>
#include <iostream>
@@ -31,13 +32,13 @@ std::ostream& operator<<(std::ostream& os, const MetaData::Album& album)
void parse(MetaData::Parser& parser, const boost::filesystem::path& file)
void parse(MetaData::Parser& parser, const std::filesystem::path& file)
{
using namespace MetaData;
parser.setClusterTypeNames( {"MOOD", "GENRE"} );
boost::optional<Track> track {parser.parse(file, true)};
std::optional<Track> track {parser.parse(file, true)};
if (!track)
{
std::cerr << "Parsing failed" << std::endl;
@@ -119,11 +120,9 @@ int main(int argc, char *argv[])
try
{
Av::AvInit();
for (std::size_t i {}; i < static_cast<std::size_t>(argc - 1); ++i)
{
boost::filesystem::path file {argv[i + 1]};
std::filesystem::path file {argv[i + 1]};
std::cout << "Parsing file '" << file << "'" << std::endl;
+1 -1
View File
@@ -8,5 +8,5 @@ lms_metadata_SOURCES = \
$(top_srcdir)/src/utils/Logger.cpp \
$(top_srcdir)/src/utils/Utils.cpp
lms_metadata_CXXFLAGS=-std=c++14 -Wall -I$(top_srcdir)/src -D_REENTRANT
lms_metadata_CXXFLAGS=-std=c++17 -I$(top_srcdir)/src -D_REENTRANT
+9 -9
View File
@@ -1,11 +1,11 @@
#include <stdlib.h>
#include <stdexcept>
#include <iostream>
#include <string>
#include <chrono>
#include <random>
#include <filesystem>
#include <iostream>
#include <stdexcept>
#include <stdlib.h>
#include <string>
#include "database/Database.hpp"
#include "database/Db.hpp"
#include "database/Session.hpp"
#include "database/Track.hpp"
#include "database/Artist.hpp"
@@ -32,7 +32,7 @@ std::ostream& operator<<(std::ostream& os, const Database::Track::pointer& track
static
bool
getTrackFeatures(Database::Session &session, const Database::Track::pointer& track, const std::map<std::string, std::size_t>& featuresSettings, SOM::InputVector& res)
getTrackFeatures(Database::Session&, const Database::Track::pointer& track, const std::map<std::string, std::size_t>& featuresSettings, SOM::InputVector& res)
{
std::map<std::string, std::vector<double>> features;
for (const auto& featureSettings : featuresSettings)
@@ -84,13 +84,13 @@ int main(int argc, char *argv[])
for (const auto& featureSettings : featuresSettings)
nbDims += featureSettings.second;
boost::filesystem::path configFilePath = "/etc/lms.conf";
std::filesystem::path configFilePath {"/etc/lms.conf"};
if (argc >= 2)
configFilePath = std::string(argv[1], 0, 256);
ServiceProvider<Config>::create(configFilePath);
Database::Database db {getService<Config>()->getPath("working-dir") / "lms.db"};
Database::Db db {getService<Config>()->getPath("working-dir") / "lms.db"};
auto session {db.createSession()};
std::cout << "Getting all features..." << std::endl;
+2 -2
View File
@@ -4,7 +4,7 @@ lms_similarity_SOURCES = \
$(srcdir)/LmsSimilarity.cpp \
$(top_srcdir)/src/database/Artist.cpp \
$(top_srcdir)/src/database/Cluster.cpp \
$(top_srcdir)/src/database/Database.cpp \
$(top_srcdir)/src/database/Db.cpp \
$(top_srcdir)/src/database/TrackFeatures.cpp \
$(top_srcdir)/src/database/TrackList.cpp \
$(top_srcdir)/src/database/Release.cpp \
@@ -20,5 +20,5 @@ lms_similarity_SOURCES = \
$(top_srcdir)/src/utils/Logger.cpp \
$(top_srcdir)/src/utils/Utils.cpp
lms_similarity_CXXFLAGS=-std=c++14 -Wall -I$(top_srcdir)/src -D_REENTRANT
lms_similarity_CXXFLAGS=-std=c++17 -I$(top_srcdir)/src -D_REENTRANT