-
-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #47 from resucutie/dev
Merge 1.6.0 with master
- Loading branch information
Showing
110 changed files
with
5,721 additions
and
2,570 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,7 @@ | ||
distributionBase=GRADLE_USER_HOME | ||
distributionPath=wrapper/dists | ||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-bin.zip | ||
networkTimeout=10000 | ||
validateDistributionUrl=true | ||
zipStoreBase=GRADLE_USER_HOME | ||
zipStorePath=wrapper/dists | ||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-all.zip |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
tags: | ||
import: | ||
single: | ||
multi: | ||
accurate: | ||
identify: | ||
download: | ||
websites: | ||
|
||
danbooru1: | ||
moebooru: | ||
danbooru2: | ||
e621: | ||
gelbooru025: | ||
gelbooru020: | ||
gelbooru01: | ||
twitter: | ||
furaffinity: | ||
instagram: |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
part of preset; | ||
|
||
// danbooru2 and e621/e926 share the same api endpoints when it comes to pools | ||
// danbooru 2: if you add .json at the end of the post url, it'll return the JSON of that post | ||
Future<VirtualPresetCollection> _danbooru2LikeAPIs(Uri uri, Function(Uri uri, {HandleChunk handleChunk}) importer) async { | ||
final res = await lbHttp.get(Uri.parse("${[uri.origin, uri.path].join("/")}.json")); | ||
final json = jsonDecode(res.body); | ||
|
||
final presets = await multiImageDownloader( | ||
postsToIterate: List<int>.from(json["post_ids"]), | ||
getter: (post, handler) { | ||
return importer(Uri.parse([uri.origin, "posts", post].join("/")), handleChunk: handler,); | ||
}, | ||
); | ||
|
||
return VirtualPresetCollection( | ||
name: (json["name"] as String).replaceAll("_", " "), | ||
pages: addSourceToAllPresets(presets, [uri.origin, uri.path].join("/")) | ||
); | ||
} | ||
Future<VirtualPresetCollection> danbooru2ToCollectionPreset(Uri uri) => _danbooru2LikeAPIs(uri, danbooru2ToPresetImage); | ||
Future<VirtualPresetCollection> e621ToCollectionPreset(Uri uri) => _danbooru2LikeAPIs(uri, e621ToPresetImage); | ||
|
||
// danbooru 1: /pool/show.xml?id=(id) returns all of the posts already parsed | ||
Future<VirtualPresetCollection> danbooru1ToCollectionPreset(Uri uri) async { | ||
final id = uri.pathSegments.last; | ||
final res = await lbHttp.get(Uri.parse("${uri.origin}/pool/show.json?id=$id")); | ||
final json = jsonDecode(res.body); | ||
|
||
final presets = await multiImageDownloader( | ||
postsToIterate: List<Map<String, dynamic>>.from(json["posts"]), | ||
getter: (post, handler) { | ||
return anyURLToPresetImage(post["file_url"], handleChunk: handler); | ||
}, | ||
); | ||
|
||
return VirtualPresetCollection( | ||
name: (json["name"] as String).replaceAll("_", " "), | ||
pages: addSourceToAllPresets(presets, [uri.origin, uri.path].join("/")) | ||
); | ||
} | ||
|
||
|
||
List<PresetImage> addSourceToAllPresets(List<PresetImage> presets, String source) { | ||
return presets.map((preset) { | ||
if(preset.sources == null) preset.sources = [source]; | ||
else preset.sources!.add(source); | ||
return preset; | ||
},).toList(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
import 'package:flutter/material.dart'; | ||
import 'package:localbooru/api/preset/index.dart'; | ||
import 'package:localbooru/utils/download_image.dart'; | ||
import 'package:localbooru/utils/listeners.dart'; | ||
|
||
Future<List<PresetImage>> multiImageDownloader<T>({ | ||
required List<T> postsToIterate, | ||
required Future<PresetImage> Function(T post, HandleChunk handler) getter, | ||
Duration? debounce | ||
}) async { | ||
final completionist = MultiCompletionist(postsToIterate.length); | ||
|
||
List<PresetImage> presets = []; | ||
|
||
for(final (index, post) in postsToIterate.indexed) { | ||
debugPrint("Adding post $post (${index + 1} of ${postsToIterate.length})"); | ||
presets.add(await getter(post, completionist.chunkHandler(index))); | ||
if(debounce != null) await Future.delayed(debounce); | ||
} | ||
|
||
return presets; | ||
} | ||
|
||
class MultiCompletionist { | ||
MultiCompletionist(this.amount); | ||
final int amount; | ||
final Map<dynamic, _Operation> _operations = {}; | ||
|
||
HandleChunk chunkHandler(dynamic id) { | ||
return (chunk, res) { | ||
if(res.contentLength == null) return; | ||
if(!_operations.containsKey(id)) { | ||
_operations[id] = _Operation( | ||
downloaded: 0, | ||
sizeOfContent: res.contentLength! | ||
); | ||
} | ||
_operations[id]!.downloaded += chunk.length; | ||
_updateProgress(); | ||
}; | ||
} | ||
|
||
_updateProgress() { | ||
final operations = _operations.values; | ||
double finalVal = 0; | ||
for(final operation in operations) { | ||
finalVal += operation.downloaded / operation.sizeOfContent; | ||
} | ||
importListener.updateImportStatus(progress: finalVal / amount); | ||
} | ||
} | ||
|
||
class _Operation { | ||
_Operation({required this.downloaded, required this.sizeOfContent}); | ||
int downloaded; | ||
int sizeOfContent; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
part of preset; | ||
|
||
// furaffinity: it doesn't offer an api, but fxraffinity exists, and it bypasses the nsfw sign up wall, so we can extract its embed to | ||
// obtain its image. the url nor fxraffinity's embed gives any clue about the poster, but furryaffinity's website title, as well as its | ||
// embed title gives, so we just fetch those (and also bypasses the nsfw sign up wall) | ||
Future<PresetImage> furaffinityToPresetImage(Uri uri) async { | ||
final fxReq = Request("Get", Uri.parse(["https://fxraffinity.net", uri.path, "?full"].join()))..followRedirects = false; | ||
final res = await Response.fromStream(await lbHttp.send(fxReq)); | ||
final websiteRes = await lbHttp.get(Uri.parse(["https://furaffinity.net", uri.path].join())); | ||
|
||
final fileUrl = getMetaProperty(parse(res.body), property: "og:image"); | ||
if(fileUrl == null) throw "Could not grab image"; | ||
|
||
final title = getMetaProperty(parse(websiteRes.body), property: "og:title"); | ||
|
||
final downloadedFileInfo = await downloadFile(Uri.parse(fileUrl)); | ||
|
||
return PresetImage( | ||
image: downloadedFileInfo, | ||
sources: [["https://furaffinity.net", uri.path].join()], | ||
tags: { | ||
"artist": title != null ? [title.split(" ").last.toLowerCase()] : [], | ||
} | ||
); | ||
} | ||
|
||
// devianart: use their oEmbed API | ||
Future<PresetImage> deviantartToPresetImage(String url) async { | ||
final res = await lbHttp.get(Uri.parse(["https://backend.deviantart.com/oembed?url=", url].join())); | ||
final json = jsonDecode(res.body); | ||
|
||
final downloadedFileInfo = await downloadFile(Uri.parse(json["url"])); | ||
|
||
return PresetImage( | ||
image: downloadedFileInfo, | ||
sources: [url], | ||
tags: { | ||
"artist": [json["author_name"].toLowerCase()], | ||
} | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
part of preset; | ||
|
||
// twitter: fxtwitter offers a url to give only the image. getting the artist is as easy as reading the first path segment | ||
Future<PresetImage> twitterToPresetImage(Uri uri) async { | ||
// final res = await http.get(Uri.parse(["https://d.fxtwitter.com", uri.path].join())); | ||
|
||
final downloadedFileInfo = await downloadFile(Uri.parse(["https://d.fxtwitter.com", uri.path].join())); | ||
|
||
return PresetImage( | ||
image: downloadedFileInfo, | ||
sources: [["https://x.com", uri.path].join("")], | ||
tags: { | ||
"artist": List<String>.from([uri.pathSegments[0].toLowerCase()]), | ||
} | ||
); | ||
} | ||
|
||
// twitter: instafix offers a url to give only the image. getting the artist is as easy as reading the first path segment | ||
Future<PresetImage> instagramToPresetImage(Uri uri) async { | ||
final fxReq = Request("Get", Uri.parse(["https://ddinstagram.com", uri.path].join()))..followRedirects = false; | ||
final response = await Response.fromStream(await lbHttp.send(fxReq)); | ||
final title = getMetaProperty(parse(response.body), property: "twitter:title"); | ||
|
||
debugPrint(response.body); | ||
|
||
final downloadedFileInfo = await downloadFile(Uri.parse(["https://d.ddinstagram.com", uri.path].join())); | ||
|
||
debugPrint(downloadedFileInfo.path); | ||
|
||
return PresetImage( | ||
image: downloadedFileInfo, | ||
sources: [["https://instagram.com", uri.path].join("")], | ||
tags: { | ||
"artist": title != null ? [title.substring(1)] : [], | ||
} | ||
); | ||
} |
Oops, something went wrong.