Skip to content

Commit 1ef2499

Browse files
authored
Merge pull request #351 from scratchcpp/network
Add network API
2 parents 7bedabd + b367eec commit 1ef2499

39 files changed

+1322
-26
lines changed

CMakeLists.txt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON)
88
set(ZIP_SRC thirdparty/zip/src)
99

1010
option(LIBSCRATCHCPP_BUILD_UNIT_TESTS "Build unit tests" ON)
11+
option(LIBSCRATCHCPP_NETWORK_SUPPORT "Support for downloading projects" ON)
1112

1213
find_package(nlohmann_json 3.9.1 REQUIRED)
1314
find_package(utf8cpp REQUIRED)
@@ -70,6 +71,15 @@ target_link_libraries(scratchcpp PRIVATE nlohmann_json::nlohmann_json)
7071
target_link_libraries(scratchcpp PRIVATE utf8cpp)
7172
target_link_libraries(scratchcpp PRIVATE zip)
7273

74+
if (LIBSCRATCHCPP_NETWORK_SUPPORT)
75+
include(FetchContent)
76+
FetchContent_Declare(cpr GIT_REPOSITORY https://github.com/libcpr/cpr.git
77+
GIT_TAG 3b15fa82ea74739b574d705fea44959b58142eb8) # 1.10.5
78+
FetchContent_MakeAvailable(cpr)
79+
target_link_libraries(scratchcpp PRIVATE cpr::cpr)
80+
target_compile_definitions(scratchcpp PRIVATE LIBSCRATCHCPP_NETWORK_SUPPORT)
81+
endif()
82+
7383
target_compile_definitions(scratchcpp PRIVATE LIBSCRATCHCPP_LIBRARY)
7484

7585
if (LIBSCRATCHCPP_BUILD_UNIT_TESTS)

README.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,11 @@ int main(int argc, char **argv) {
108108
}
109109
```
110110
111+
Loading projects from [scratch.mit.edu](https://scratch.mit.edu/) is supported too:
112+
```cpp
113+
libscratchcpp::Project p("https://scratch.mit.edu/projects/XXXXXX");
114+
```
115+
111116
<!-- TODO: Add link to documentation -->
112117

113118
<p align="right">(<a href="#readme-top">back to top</a>)</p>
@@ -139,7 +144,7 @@ int main(int argc, char **argv) {
139144
- [ ] Scratch 2.0 to 3.0 converter (help needed)
140145
- [ ] Scratch 1.4 and below to 3.0 converter (help needed)
141146
- [ ] API for comments
142-
- [ ] API for loading projects from URL
147+
- [x] API for loading projects from URL
143148

144149
See the [open issues](https://github.com/scratchcpp/libscratchcpp/issues) for a full list of proposed features (and known issues).
145150

include/scratchcpp/project.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#pragma once
44

55
#include <memory>
6+
#include <functional>
67
#include "spimpl.h"
78

89
#include "global.h"
@@ -14,7 +15,11 @@ class ProjectPrivate;
1415

1516
class IEngine;
1617

17-
/*! \brief The Project class provides API for reading and running Scratch projects. */
18+
/*!
19+
* \brief The Project class provides API for reading and running Scratch projects.
20+
*
21+
* \note Loading online projects is supported if the LIBSCRATCHCPP_NETWORK_SUPPORT option is set, just use setFileName("some URL")
22+
*/
1823
class LIBSCRATCHCPP_EXPORT Project
1924
{
2025
public:
@@ -37,6 +42,8 @@ class LIBSCRATCHCPP_EXPORT Project
3742

3843
std::shared_ptr<IEngine> engine() const;
3944

45+
void setDownloadProgressCallback(const std::function<void(unsigned int, unsigned int)> &&f);
46+
4047
private:
4148
spimpl::unique_impl_ptr<ProjectPrivate> impl;
4249
};

src/internal/CMakeLists.txt

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,30 @@ target_sources(scratchcpp
66
reader_common.h
77
zipreader.cpp
88
zipreader.h
9+
projecturl.cpp
10+
projecturl.h
11+
idownloader.h
12+
idownloaderfactory.h
13+
iprojectdownloader.h
14+
iprojectdownloaderfactory.h
15+
projectdownloaderfactory.cpp
16+
projectdownloaderfactory.h
917
)
18+
19+
if (LIBSCRATCHCPP_NETWORK_SUPPORT)
20+
target_sources(scratchcpp
21+
PRIVATE
22+
downloader.cpp
23+
downloader.h
24+
downloaderfactory.cpp
25+
downloaderfactory.h
26+
projectdownloader.cpp
27+
projectdownloader.h
28+
)
29+
else()
30+
target_sources(scratchcpp
31+
PRIVATE
32+
projectdownloaderstub.cpp
33+
projectdownloaderstub.h
34+
)
35+
endif()

src/internal/downloader.cpp

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
// SPDX-License-Identifier: Apache-2.0
2+
3+
#include <iostream>
4+
5+
#include "downloader.h"
6+
7+
using namespace libscratchcpp;
8+
9+
Downloader::Downloader()
10+
{
11+
m_session.SetTimeout(cpr::Timeout(5000));
12+
}
13+
14+
bool Downloader::download(const std::string &url)
15+
{
16+
m_session.SetUrl(cpr::Url(url));
17+
m_response = m_session.Get();
18+
19+
if (m_response.status_code != 200) {
20+
std::cerr << "download error: " << m_response.error.message << std::endl;
21+
22+
if (m_response.status_code != 0)
23+
std::cerr << "code: " << m_response.status_code << std::endl;
24+
25+
std::cerr << "URL: " << url << std::endl;
26+
return false;
27+
}
28+
29+
return true;
30+
}
31+
32+
const std::string &Downloader::text() const
33+
{
34+
return m_response.text;
35+
}

src/internal/downloader.h

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// SPDX-License-Identifier: Apache-2.0
2+
3+
#pragma once
4+
5+
#include <cpr/api.h>
6+
#include <cpr/response.h>
7+
8+
#include "idownloader.h"
9+
10+
namespace libscratchcpp
11+
{
12+
13+
class Downloader : public IDownloader
14+
{
15+
public:
16+
Downloader();
17+
18+
bool download(const std::string &url) override;
19+
const std::string &text() const override;
20+
21+
private:
22+
cpr::Session m_session;
23+
cpr::Response m_response;
24+
};
25+
26+
} // namespace libscratchcpp

src/internal/downloaderfactory.cpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// SPDX-License-Identifier: Apache-2.0
2+
3+
#include "downloaderfactory.h"
4+
#include "downloader.h"
5+
6+
using namespace libscratchcpp;
7+
8+
std::shared_ptr<DownloaderFactory> DownloaderFactory::m_instance = std::make_shared<DownloaderFactory>();
9+
10+
DownloaderFactory::DownloaderFactory()
11+
{
12+
}
13+
14+
std::shared_ptr<DownloaderFactory> DownloaderFactory::instance()
15+
{
16+
return m_instance;
17+
}
18+
19+
std::shared_ptr<IDownloader> DownloaderFactory::create() const
20+
{
21+
return std::make_shared<Downloader>();
22+
}

src/internal/downloaderfactory.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// SPDX-License-Identifier: Apache-2.0
2+
3+
#pragma once
4+
5+
#include "idownloaderfactory.h"
6+
7+
namespace libscratchcpp
8+
{
9+
10+
class DownloaderFactory : public IDownloaderFactory
11+
{
12+
public:
13+
DownloaderFactory();
14+
15+
static std::shared_ptr<DownloaderFactory> instance();
16+
std::shared_ptr<IDownloader> create() const override;
17+
18+
private:
19+
static std::shared_ptr<DownloaderFactory> m_instance;
20+
};
21+
22+
} // namespace libscratchcpp

src/internal/idownloader.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// SPDX-License-Identifier: Apache-2.0
2+
3+
#pragma once
4+
5+
#include <string>
6+
7+
namespace libscratchcpp
8+
{
9+
10+
class IDownloader
11+
{
12+
public:
13+
virtual ~IDownloader() { }
14+
15+
virtual bool download(const std::string &url) = 0;
16+
virtual const std::string &text() const = 0;
17+
};
18+
19+
} // namespace libscratchcpp

src/internal/idownloaderfactory.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// SPDX-License-Identifier: Apache-2.0
2+
3+
#pragma once
4+
5+
#include <memory>
6+
7+
namespace libscratchcpp
8+
{
9+
10+
class IDownloader;
11+
12+
class IDownloaderFactory
13+
{
14+
public:
15+
virtual ~IDownloaderFactory() { }
16+
17+
virtual std::shared_ptr<IDownloader> create() const = 0;
18+
};
19+
20+
} // namespace libscratchcpp

0 commit comments

Comments
 (0)