Commit d57eedc5 authored by Peter C. Ndikuwera's avatar Peter C. Ndikuwera
Browse files

Fix NFS & SMB/CIFS Remote collection

BUG: 249760
CCBUG: 232976
CCBUG: 171213
CCBUG: 187692

Using Max's Mass Storage Device code as a guide, this commit returns
network-based collections, shared over NFS & SMB/CIFS to the dynamic
collection architecture.

This should re-validate http://amarok.kde.org/wiki/Dynamic_Collection,
which some people have complained to longer applies.

Test it & break it!
parent dace64d7
......@@ -30,7 +30,7 @@
#include <solid/device.h>
#include <solid/deviceinterface.h>
#include <solid/devicenotifier.h>
#include <solid/storagevolume.h>
#include <solid/storageaccess.h>
#include <threadweaver/Job.h>
#include <threadweaver/ThreadWeaver.h>
......@@ -111,7 +111,7 @@ MountPointManager::init()
else
debug() << "Plugin could not be loaded";
Solid::Predicate predicate = Solid::Predicate( Solid::DeviceInterface::StorageVolume );
Solid::Predicate predicate = Solid::Predicate( Solid::DeviceInterface::StorageAccess );
QList<Solid::Device> devices = Solid::Device::listFromQuery( predicate );
foreach( const Solid::Device &device, devices )
createHandlerFromDevice( device, device.udi() );
......@@ -435,7 +435,7 @@ void
MountPointManager::deviceAdded( const QString &udi )
{
DEBUG_BLOCK
Solid::Predicate predicate = Solid::Predicate( Solid::DeviceInterface::StorageVolume );
Solid::Predicate predicate = Solid::Predicate( Solid::DeviceInterface::StorageAccess );
QList<Solid::Device> devices = Solid::Device::listFromQuery( predicate );
//Looking for a specific udi in predicate seems flaky/buggy; the foreach loop barely
//takes any time, so just be safe
......
include_directories( ${KDE4_INCLUDE_DIR} ${QT_INCLUDES} )
add_subdirectory( massstorage )
#add_subdirectory( nfs )
#add_subdirectory( smb )
add_subdirectory( nfs )
add_subdirectory( smb )
include_directories( ${CMAKE_CURRENT_SOURCE_DIR}/../..
${CMAKE_CURRENT_SOURCE_DIR}/../../device
${KDE4_INCLUDE_DIR} ${QT_INCLUDES} )
include_directories(
${Amarok_SOURCE_DIR}/src/plugin
${Amarok_SOURCE_DIR}/src/collection/sqlcollection
${KDE4_INCLUDE_DIR}
${QT_INCLUDES}
)
########### next target ###############
......@@ -9,12 +12,17 @@ set(amarok_nfs-device_PART_SRCS NfsDeviceHandler.cpp )
kde4_add_plugin(amarok_nfs-device
${amarok_nfs-device_PART_SRCS})
target_link_libraries(amarok_nfs-device amarok ${KDE4_KDECORE_LIBS} )
target_link_libraries(amarok_nfs-device
amarok-sqlcollection
amaroklib
amarokcore
${KDE4_KDECORE_LIBS}
${KDE4_SOLID_LIBS} )
install( TARGETS amarok_nfs-device DESTINATION ${PLUGIN_INSTALL_DIR} )
install(TARGETS amarok_nfs-device DESTINATION ${PLUGIN_INSTALL_DIR} )
########### install files ###############
install( FILES amarok_nfs-device.desktop DESTINATION ${SERVICES_INSTALL_DIR} )
install(FILES amarok_nfs-device.desktop DESTINATION ${SERVICES_INSTALL_DIR})
/****************************************************************************************
* Copyright (c) 2006-2007 Maximilian Kossick <maximilian.kossick@googlemail.com> *
* Copyright (c) 2011 Peter C. Ndikuwera <pndiku@gmail.com> *
* *
* This program is free software; you can redistribute it and/or modify it under *
* the terms of the GNU General Public License as published by the Free Software *
......@@ -13,23 +14,40 @@
* You should have received a copy of the GNU General Public License along with *
* this program. If not, see <http://www.gnu.org/licenses/>. *
****************************************************************************************/
#define DEBUG_PREFIX "NfsDeviceHandler"
#include "NfsDeviceHandler.h"
AMAROK_EXPORT_PLUGIN( NfsDeviceHandlerFactory )
#include "core/support/Debug.h"
#include "core/collections/support/SqlStorage.h"
#include <KConfig>
#include <KUrl>
#include <kconfig.h>
#include <kurl.h>
#include <kmountpoint.h>
#include <solid/storagevolume.h>
#include <solid/storageaccess.h>
NfsDeviceHandler::NfsDeviceHandler( int deviceId, QString server, QString dir, QString mountPoint )
NfsDeviceHandler::NfsDeviceHandler( int deviceId, const QString &server, const QString &share, const QString &mountPoint, const QString &udi )
: DeviceHandler()
, m_deviceID( deviceId )
, m_mountPoint( mountPoint )
, m_server( server )
, m_dir( dir )
, m_share( share )
, m_mountPoint( mountPoint )
, m_udi( udi )
{
DEBUG_BLOCK
}
NfsDeviceHandler::NfsDeviceHandler( int deviceId, const QString &mountPoint, const QString &udi )
: DeviceHandler()
, m_deviceID( deviceId )
, m_mountPoint( mountPoint )
, m_udi( udi )
{
DEBUG_BLOCK
}
NfsDeviceHandler::~NfsDeviceHandler()
......@@ -55,58 +73,66 @@ NfsDeviceHandler::getDeviceID()
return m_deviceID;
}
const QString &
NfsDeviceHandler::getDevicePath() const
const QString &NfsDeviceHandler::getDevicePath() const
{
return m_mountPoint;
}
void
NfsDeviceHandler::getURL( KUrl &absolutePath, const KUrl &relativePath )
void NfsDeviceHandler::getURL( KUrl &absolutePath, const KUrl &relativePath )
{
absolutePath.setPath( m_mountPoint );
absolutePath.addPath( relativePath.path() );
absolutePath.cleanPath();
}
void
NfsDeviceHandler::getPlayableURL( KUrl &absolutePath, const KUrl &relativePath )
void NfsDeviceHandler::getPlayableURL( KUrl &absolutePath, const KUrl &relativePath )
{
getURL( absolutePath, relativePath );
}
bool
NfsDeviceHandler::deviceIsMedium( const Medium * m ) const
bool NfsDeviceHandler::deviceMatchesUdi( const QString &udi ) const
{
return m->deviceNode() == m_server + ':' + m_dir;
return m_udi == udi;
}
///////////////////////////////////////////////////////////////////////////////
// class NfsDeviceHandlerFactory
///////////////////////////////////////////////////////////////////////////////
QString
NfsDeviceHandlerFactory::type( ) const
QString NfsDeviceHandlerFactory::type( ) const
{
return "nfs";
}
bool
NfsDeviceHandlerFactory::canCreateFromMedium( ) const
bool NfsDeviceHandlerFactory::canCreateFromMedium( ) const
{
return true;
}
bool
NfsDeviceHandlerFactory::canCreateFromConfig( ) const
bool NfsDeviceHandlerFactory::canCreateFromConfig( ) const
{
return false;
}
bool
NfsDeviceHandlerFactory::canHandle( const Medium * m ) const
bool NfsDeviceHandlerFactory::canHandle( const Solid::Device &device ) const
{
return m && m->fsType() == "nfs" && m->isMounted();
DEBUG_BLOCK
const Solid::StorageAccess *access = device.as<Solid::StorageAccess>();
if( !access || access->filePath().isEmpty() )
{
debug() << "Device not accessible";
return false;
}
// find mount point
KMountPoint::Ptr m = KMountPoint::currentMountPoints().findByPath( access->filePath() );
if ( m && m->mountType() == "nfs" )
return true;
return false;
}
NfsDeviceHandlerFactory::NfsDeviceHandlerFactory( )
......@@ -118,17 +144,38 @@ NfsDeviceHandlerFactory::~NfsDeviceHandlerFactory( )
}
DeviceHandler *
NfsDeviceHandlerFactory::createHandler( KSharedConfigPtr ) const
NfsDeviceHandlerFactory::createHandler( KSharedConfigPtr, SqlStorage* ) const
{
return 0;
}
DeviceHandler *
NfsDeviceHandlerFactory::createHandler( const Medium * m ) const
NfsDeviceHandlerFactory::createHandler( const Solid::Device &device, const QString &udi, SqlStorage *s ) const
{
SqlStorage *s = CollectionManager::instance()->sqlStorage();
QString server = m->deviceNode().section( ':', 0, 0 );
QString share = m->deviceNode().section( ':', 1, 1 );
DEBUG_BLOCK
if( !s )
{
debug() << "!s, returning 0";
return 0;
}
const Solid::StorageAccess *access = device.as<Solid::StorageAccess>();
if( !access )
{
debug() << "Device isn't valid, can't create a handler";
return 0;
}
if( access->filePath().isEmpty() )
{
debug() << "not mounted, can't do anything";
return 0; // It's not mounted, we can't do anything.
}
// find mount point
KMountPoint::Ptr m = KMountPoint::currentMountPoints().findByPath( access->filePath() );
QString server = m->mountedFrom().section( ':', 0, 0 );
QString share = m->mountedFrom().section( ':', 1, 1 );
QStringList ids = s->query( QString( "SELECT id, label, lastmountpoint "
"FROM devices WHERE type = 'nfs' "
"AND servername = '%1' AND sharename = '%2';" )
......@@ -141,7 +188,7 @@ NfsDeviceHandlerFactory::createHandler( const Medium * m ) const
"id = %1;" )
.arg( ids[0] )
.arg( s->escape( m->mountPoint() ) ) );
return new NfsDeviceHandler( ids[0].toInt(), server, share, m->mountPoint() );
return new NfsDeviceHandler( ids[0].toInt(), server, share, m->mountPoint(), udi );
}
else
{
......@@ -158,7 +205,7 @@ NfsDeviceHandlerFactory::createHandler( const Medium * m ) const
return 0;
}
debug() << "Created new NFS device with ID " << id << " , server " << server << " ,share " << share;
return new NfsDeviceHandler( id, server, share, m->mountPoint() );
return new NfsDeviceHandler( id, server, share, m->mountPoint(), udi );
}
}
/****************************************************************************************
* Copyright (c) 2006-2007 Maximilian Kossick <maximilian.kossick@googlemail.com> *
* Copyright (c) 2011 Peter C. Ndikuwera <pndiku@gmail.com> *
* *
* This program is free software; you can redistribute it and/or modify it under *
* the terms of the GNU General Public License as published by the Free Software *
......@@ -25,26 +26,28 @@ public:
NfsDeviceHandlerFactory();
virtual ~NfsDeviceHandlerFactory();
virtual bool canHandle( const Medium* m ) const;
virtual bool canHandle( const Solid::Device &device ) const;
virtual bool canCreateFromMedium() const;
virtual DeviceHandler* createHandler( const Medium* m ) const;
virtual DeviceHandler* createHandler( const Solid::Device &device, const QString &uuid, SqlStorage *s ) const;
virtual bool canCreateFromConfig() const;
virtual DeviceHandler* createHandler( KSharedConfigPtr c ) const;
virtual DeviceHandler* createHandler( KSharedConfigPtr c, SqlStorage *s ) const;
virtual QString type() const;
};
/**
@author Maximilian Kossick <maximilian.kossick@googlemail.com>
@author Maximilian Kossick <maximilian.kossick@googlemail.com>
*/
class NfsDeviceHandler : public DeviceHandler
{
public:
NfsDeviceHandler(int deviceId, QString server, QString dir, QString mountPoint );
NfsDeviceHandler();
NfsDeviceHandler(int deviceId, const QString &mountPoint, const QString &udi );
NfsDeviceHandler(int deviceId, const QString &server, const QString &share, const QString &mountPoint, const QString &udi );
virtual ~NfsDeviceHandler();
......@@ -54,14 +57,15 @@ public:
virtual const QString &getDevicePath() const;
virtual void getURL( KUrl &absolutePath, const KUrl &relativePath );
virtual void getPlayableURL( KUrl &absolutePath, const KUrl &relativePath );
virtual bool deviceIsMedium( const Medium *m ) const;
virtual bool deviceMatchesUdi( const QString &udi ) const;
private:
int m_deviceID;
const QString m_mountPoint;
QString m_server;
QString m_dir;
QString m_share;
const QString m_mountPoint;
QString m_udi;
};
......
include_directories( ${CMAKE_CURRENT_SOURCE_DIR}/../..
${CMAKE_CURRENT_SOURCE_DIR}/../../device
${KDE4_INCLUDE_DIR} ${QT_INCLUDES} )
include_directories(
${Amarok_SOURCE_DIR}/src/plugin
${Amarok_SOURCE_DIR}/src/collection/sqlcollection
${KDE4_INCLUDE_DIR}
${QT_INCLUDES}
)
########### next target ###############
......@@ -9,12 +12,17 @@ set(amarok_smb-device_PART_SRCS SmbDeviceHandler.cpp )
kde4_add_plugin(amarok_smb-device
${amarok_smb-device_PART_SRCS})
target_link_libraries(amarok_smb-device amarok ${KDE4_KDECORE_LIBS} )
target_link_libraries(amarok_smb-device
amarok-sqlcollection
amaroklib
amarokcore
${KDE4_KDECORE_LIBS}
${KDE4_SOLID_LIBS} )
install( TARGETS amarok_smb-device DESTINATION ${PLUGIN_INSTALL_DIR} )
install(TARGETS amarok_smb-device DESTINATION ${PLUGIN_INSTALL_DIR} )
########### install files ###############
install( FILES amarok_smb-device.desktop DESTINATION ${SERVICES_INSTALL_DIR} )
install(FILES amarok_smb-device.desktop DESTINATION ${SERVICES_INSTALL_DIR})
/****************************************************************************************
* Copyright (c) 2006-2007 Maximilian Kossick <maximilian.kossick@googlemail.com> *
* Copyright (c) 2011 Peter C. Ndikuwera <pndiku@gmail.com> *
* *
* This program is free software; you can redistribute it and/or modify it under *
* the terms of the GNU General Public License as published by the Free Software *
......@@ -13,24 +14,40 @@
* You should have received a copy of the GNU General Public License along with *
* this program. If not, see <http://www.gnu.org/licenses/>. *
****************************************************************************************/
#define DEBUG_PREFIX "SmbDeviceHandler"
#include "SmbDeviceHandler.h"
AMAROK_EXPORT_PLUGIN( SmbDeviceHandlerFactory )
#include "core/support/Debug.h"
#include "core/collections/support/SqlStorage.h"
#include <KConfig>
#include <KUrl>
#include <kconfig.h>
#include <kurl.h>
#include <kmountpoint.h>
#include <solid/storagevolume.h>
#include <solid/storageaccess.h>
SmbDeviceHandler::SmbDeviceHandler( int deviceId, const QString &server, const QString &share, const QString &mountPoint, const QString &udi )
: DeviceHandler()
, m_deviceID( deviceId )
, m_server( server )
, m_share( share )
, m_mountPoint( mountPoint )
, m_udi( udi )
{
DEBUG_BLOCK
}
SmbDeviceHandler::SmbDeviceHandler( int deviceId, QString server, QString dir, QString mountPoint )
SmbDeviceHandler::SmbDeviceHandler( int deviceId, const QString &mountPoint, const QString &udi )
: DeviceHandler()
, m_deviceID( deviceId )
, m_mountPoint( mountPoint )
, m_server( server )
, m_dir( dir )
, m_udi( udi )
{
DEBUG_BLOCK
}
SmbDeviceHandler::~SmbDeviceHandler()
......@@ -56,60 +73,66 @@ SmbDeviceHandler::getDeviceID()
return m_deviceID;
}
const QString &
SmbDeviceHandler::getDevicePath() const
const QString &SmbDeviceHandler::getDevicePath() const
{
return m_mountPoint;
}
void
SmbDeviceHandler::getURL( KUrl &absolutePath, const KUrl &relativePath )
void SmbDeviceHandler::getURL( KUrl &absolutePath, const KUrl &relativePath )
{
absolutePath.setPath( m_mountPoint );
absolutePath.addPath( relativePath.path() );
absolutePath.cleanPath();
}
void
SmbDeviceHandler::getPlayableURL( KUrl &absolutePath, const KUrl &relativePath )
void SmbDeviceHandler::getPlayableURL( KUrl &absolutePath, const KUrl &relativePath )
{
getURL( absolutePath, relativePath );
}
bool
SmbDeviceHandler::deviceIsMedium( const Medium * m ) const
bool SmbDeviceHandler::deviceMatchesUdi( const QString &udi ) const
{
return m->deviceNode() == m_server + ':' + m_dir;
return m_udi == udi;
}
///////////////////////////////////////////////////////////////////////////////
// class SmbDeviceHandlerFactory
///////////////////////////////////////////////////////////////////////////////
QString
SmbDeviceHandlerFactory::type( ) const
QString SmbDeviceHandlerFactory::type( ) const
{
return "smb";
}
bool
SmbDeviceHandlerFactory::canCreateFromMedium( ) const
bool SmbDeviceHandlerFactory::canCreateFromMedium( ) const
{
return true;
}
bool
SmbDeviceHandlerFactory::canCreateFromConfig( ) const
bool SmbDeviceHandlerFactory::canCreateFromConfig( ) const
{
return false;
}
bool
SmbDeviceHandlerFactory::canHandle( const Medium * m ) const
bool SmbDeviceHandlerFactory::canHandle( const Solid::Device &device ) const
{
return m && ( m->fsType().find( "smb" ) != -1 ||
m->fsType().find( "cifs" ) != -1 )
&& m->isMounted();
DEBUG_BLOCK
const Solid::StorageAccess *access = device.as<Solid::StorageAccess>();
if( !access || access->filePath().isEmpty() )
{
debug() << "Device not accessible";
return false;
}
// find mount point
KMountPoint::Ptr m = KMountPoint::currentMountPoints().findByPath( access->filePath() );
if ( m && (m->mountType() == "smb" || m->mountType() == "cifs") )
return true;
return false;
}
SmbDeviceHandlerFactory::SmbDeviceHandlerFactory( )
......@@ -121,17 +144,38 @@ SmbDeviceHandlerFactory::~SmbDeviceHandlerFactory( )
}
DeviceHandler *
SmbDeviceHandlerFactory::createHandler( KSharedConfigPtr ) const
SmbDeviceHandlerFactory::createHandler( KSharedConfigPtr, SqlStorage* ) const
{
return 0;
}
DeviceHandler *
SmbDeviceHandlerFactory::createHandler( const Medium * m ) const
SmbDeviceHandlerFactory::createHandler( const Solid::Device &device, const QString &udi, SqlStorage *s ) const
{
SqlStorage *s = CollectionManager::instance()->sqlStorage();
QString server = m->deviceNode().section( '/', 2, 2 );
QString share = m->deviceNode().section( '/', 3, 3 );
DEBUG_BLOCK
if( !s )
{
debug() << "!s, returning 0";
return 0;
}
const Solid::StorageAccess *access = device.as<Solid::StorageAccess>();
if( !access )
{
debug() << "Device isn't valid, can't create a handler";
return 0;
}
if( access->filePath().isEmpty() )
{
debug() << "not mounted, can't do anything";
return 0; // It's not mounted, we can't do anything.
}
// find out the mount type of this...
KMountPoint::Ptr m = KMountPoint::currentMountPoints().findByPath( access->filePath() );
QString server = m->mountedFrom().section( '/', 2, 2 );
QString share = m->mountedFrom().section( '/', 3, 3 );
QStringList ids = s->query( QString( "SELECT id, label, lastmountpoint "
"FROM devices WHERE type = 'smb' "
"AND servername = '%1' AND sharename = '%2';" )
......@@ -144,7 +188,7 @@ SmbDeviceHandlerFactory::createHandler( const Medium * m ) const
"id = %1;" )
.arg( ids[0] )
.arg( s->escape( m->mountPoint() ) ) );
return new SmbDeviceHandler( ids[0].toInt(), server, share, m->mountPoint() );
return new SmbDeviceHandler( ids[0].toInt(), server, share, m->mountPoint(), udi );
}
else
{
......@@ -161,7 +205,7 @@ SmbDeviceHandlerFactory::createHandler( const Medium * m ) const
return 0;
}
debug() << "Created new SMB device with ID " << id << " , server " << server << " ,share " << share;
return new SmbDeviceHandler( id, server, share, m->mountPoint() );
return new SmbDeviceHandler( id, server, share, m->mountPoint(), udi );
}
}
/****************************************************************************************
* Copyright (c) 2006-2007 Maximilian Kossick <maximilian.kossick@googlemail.com> *
* Copyright (c) 2011 Peter C. Ndikuwera <pndiku@gmail.com> *
* *
* This program is free software; you can redistribute it and/or modify it under *
* the terms of the GNU General Public License as published by the Free Software *
......@@ -13,7 +14,7 @@
* You should have received a copy of the GNU General Public License along with *
* this program. If not, see <http://www.gnu.org/licenses/>. *
****************************************************************************************/
#ifndef SMBDEVICEHANDLER_H
#define SMBDEVICEHANDLER_H
......@@ -29,22 +30,24 @@ public:
virtual bool canCreateFromMedium() const;
virtual DeviceHandler* createHandler( const Solid::Device &volume, const QString &udi ) const;
virtual DeviceHandler* createHandler( const Solid::Device &device, const QString &uuid, SqlStorage *s ) const;
virtual bool canCreateFromConfig() const;
virtual DeviceHandler* createHandler( KSharedConfigPtr c ) const;
virtual DeviceHandler* createHandler( KSharedConfigPtr c, SqlStorage *s ) const;
virtual QString type() const;
};