• R/O
  • HTTP
  • SSH
  • HTTPS

Commit

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

D wrapper around (some) of the pixiv web API


Commit MetaInfo

Révisionb92948ac0f252dcebc91ac0482b6556acec037ec (tree)
l'heure2023-08-13 11:15:44
Auteursupercell <stigma@disr...>
Commitersupercell

Message de Log

Start implementation of partial downloads

Currently it's limited to single-paged illustrations; Some cleanup and
refactoring is needed first.

Change Summary

Modification

--- a/source/pixivd/client.d
+++ b/source/pixivd/client.d
@@ -18,6 +18,8 @@ import pixivd.types;
1818 public enum PixivDVersion = 0.8;
1919 public enum PixivDVersionString = "0.8";
2020
21+enum kUserAgent = "Mozilla/5.0 (Windows NT 10.0; rv:108.0) Gecko/20100101 Firefox/108.0";
22+
2123 struct DownloadProgressEvent
2224 {
2325 size_t total;
@@ -44,17 +46,24 @@ class Client
4446 private:
4547
4648 string m_phpsessid;
49+
4750 HTTP m_client;
4851
4952 bool m_isGMInitialized = false;
5053
5154 public:
5255
56+ /**
57+ * Return the PHPSESSID that is being used.
58+ */
5359 @property string phpsessid() const
5460 {
5561 return m_phpsessid;
5662 }
5763
64+ /**
65+ * Set a new PHPSESSID to be used for new requests.
66+ */
5867 @property void phpsessid(string sessionID)
5968 {
6069 m_phpsessid = sessionID;
@@ -72,17 +81,19 @@ public:
7281 {
7382 m_phpsessid = phpsessid;
7483 m_client = HTTP();
75- m_client.addRequestHeader("Accept", "application/json, */*");
76- m_client.addRequestHeader("Host", "www.pixiv.net");
77- m_client.addRequestHeader("Referer", "https://www.pixiv.net/");
78- m_client.setUserAgent(
79- "Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101 Firefix/91.0");
80- if ("" != m_phpsessid)
81- {
82- m_client.setCookie("PHPSESSID=" ~ m_phpsessid);
83- }
84+ this._resetHeaders();
8485 }
8586
87+ /**
88+ * Create a new instance of Client.
89+ *
90+ * This will allow you to interact with the pixiv API without an
91+ * account. However, your access will be limited to what is
92+ * publically available.
93+ *
94+ * Use `phpsessid(string)` to set a PHPSESSID, meaning you will
95+ * be logged in.
96+ */
8697 this()
8798 {
8899 this("");
@@ -710,18 +721,36 @@ private:
710721 {
711722 import std.datetime.systime;
712723
713- import std.file : FileException, exists, setTimes;
724+ import std.file : FileException, exists, getSize, rename, setTimes;
714725 import std.path : extension;
715726 import std.stdio : File;
716727
717728 const baseFileName = illust.id ~ illust.urls["original"].extension;
729+ const partFileName = baseFileName ~ ".part";
718730
719731 if (true == exists(baseFileName) && false == overwrite)
720732 {
721733 throw new FileException(baseFileName, "File already exists");
722734 }
723735
724- File imageFile = File(baseFileName, "w+");
736+ string mode = "w+";
737+
738+ if (exists(partFileName)) {
739+ // Resume previous attempt at downloading.
740+ m_client.url = illust.urls["original"];
741+ m_client.method = HTTP.Method.head;
742+ m_client.perform();
743+ if ("accept-ranges" in m_client.responseHeaders()) {
744+ ulong bytesRead = getSize(partFileName);
745+ m_client.addRequestHeader("Range", format!"bytes=%d-"(bytesRead));
746+ mode = "a+";
747+ }
748+ // If the "accept-ranges" header was not present,
749+ // we'll restart the entire download.
750+ m_client.method = HTTP.Method.get;
751+ }
752+
753+ File imageFile = File(partFileName, mode);
725754
726755 m_client.url = illust.urls["original"];
727756 m_client.onReceive = (ubyte[] data) {
@@ -735,11 +764,13 @@ private:
735764
736765 m_client.perform();
737766 imageFile.close();
767+ rename(partFileName, baseFileName);
738768 emit(DownloadCompleteEvent());
739769
740770 SysTime createDate = SysTime.fromISOExtString(illust.createDate);
741-
742771 setTimes(baseFileName, createDate, createDate);
772+
773+ this._resetHeaders();
743774 }
744775
745776 void _downloadPagedIllust(Illustration illust, bool overwrite)
@@ -1014,4 +1045,18 @@ private:
10141045 DestroyExceptionInfo(&exception);
10151046 emit(DownloadCompleteEvent());
10161047 }
1048+
1049+ void _resetHeaders()
1050+ {
1051+ m_client.clearRequestHeaders();
1052+
1053+ m_client.addRequestHeader("Accept", "application/json, */*");
1054+ m_client.addRequestHeader("Host", "www.pixiv.net");
1055+ m_client.addRequestHeader("Referer", "https://www.pixiv.net/");
1056+ m_client.setUserAgent(kUserAgent);
1057+ if ("" != m_phpsessid)
1058+ {
1059+ m_client.setCookie("PHPSESSID=" ~ m_phpsessid);
1060+ }
1061+ }
10171062 }