From 8ef33f382e1c5f01edd6483bd05d8e00cd021e9d Mon Sep 17 00:00:00 2001 From: Yutousama <583819556@qq.com> Date: Wed, 17 Nov 2021 14:17:38 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96jellyfin=E6=90=9C=E5=88=AE?= =?UTF-8?q?=E5=99=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 4 + .../nas/Controllers/MusicController.java | 14 +- .../com/yutou/nas/Datas/Jellyfin/Chapter.java | 13 ++ .../com/yutou/nas/Datas/Jellyfin/Episode.java | 31 +++ .../yutou/nas/Datas/Jellyfin/EpisodeData.java | 78 +++++++ .../nas/Datas/Jellyfin/ImageBlurHashes.java | 12 ++ .../yutou/nas/Datas/Jellyfin/ImageTags.java | 8 + .../yutou/nas/Datas/Jellyfin/ItemInfo.java | 57 +++++ .../yutou/nas/Datas/Jellyfin/LibsItem.java | 24 +++ .../yutou/nas/Datas/Jellyfin/MediaSource.java | 37 ++++ .../yutou/nas/Datas/Jellyfin/MediaStream.java | 38 ++++ .../yutou/nas/Datas/Jellyfin/UserData.java | 12 ++ .../java/com/yutou/nas/NasApplication.java | 2 +- .../com/yutou/nas/bangumi/BangumiTools.java | 93 ++++++--- .../com/yutou/nas/utils/ApplicationInit.java | 136 ++++++------ .../yutou/nas/utils/JellyfinAPIManager.java | 196 +++++++++--------- src/main/java/com/yutou/nas/utils/Log.java | 7 + .../com/yutou/nas/utils/QQBotManager.java | 1 + src/main/java/com/yutou/nas/utils/Tools.java | 2 - 19 files changed, 574 insertions(+), 191 deletions(-) create mode 100644 src/main/java/com/yutou/nas/Datas/Jellyfin/Chapter.java create mode 100644 src/main/java/com/yutou/nas/Datas/Jellyfin/Episode.java create mode 100644 src/main/java/com/yutou/nas/Datas/Jellyfin/EpisodeData.java create mode 100644 src/main/java/com/yutou/nas/Datas/Jellyfin/ImageBlurHashes.java create mode 100644 src/main/java/com/yutou/nas/Datas/Jellyfin/ImageTags.java create mode 100644 src/main/java/com/yutou/nas/Datas/Jellyfin/ItemInfo.java create mode 100644 src/main/java/com/yutou/nas/Datas/Jellyfin/LibsItem.java create mode 100644 src/main/java/com/yutou/nas/Datas/Jellyfin/MediaSource.java create mode 100644 src/main/java/com/yutou/nas/Datas/Jellyfin/MediaStream.java create mode 100644 src/main/java/com/yutou/nas/Datas/Jellyfin/UserData.java diff --git a/pom.xml b/pom.xml index 3bdcbf0..33bca14 100644 --- a/pom.xml +++ b/pom.xml @@ -138,6 +138,10 @@ aliyun-sdk-oss 3.10.2 + diff --git a/src/main/java/com/yutou/nas/Controllers/MusicController.java b/src/main/java/com/yutou/nas/Controllers/MusicController.java index cb342cd..845230b 100644 --- a/src/main/java/com/yutou/nas/Controllers/MusicController.java +++ b/src/main/java/com/yutou/nas/Controllers/MusicController.java @@ -152,13 +152,18 @@ public class MusicController { fileName = Tools.base64ToString(fileName); } List list = null; - if (body.getString("type").equals("album")) { + if ("album".equals(body.getString("type"))) { list = musicTools.selectAlbum(fileName); } File file; if (list != null && !list.isEmpty()) { fileName = list.get(0).getFile(); } + if(!fileName.startsWith("/media/yutou/disk_lvm/public/音乐/") + ||fileName.endsWith("..") + ||fileName.endsWith("../")){ + return null; + } file = new File(fileName); if (file.exists()) { try { @@ -194,13 +199,18 @@ public class MusicController { public ResponseEntity play(String filePath, String random) { String _filePath; boolean _random; - _random = !StringUtils.isEmpty(random) && random.equals("true"); + _random = !StringUtils.isEmpty(random) && "true".equals(random); _filePath = Tools.base64ToString(filePath); if (_random) { List list = musicTools.getMusicList(); MusicData data = list.get(Tools.randomCommon(0, list.size() - 1, 1)[0]); _filePath = data.getFile(); } + if(!_filePath.startsWith("/media/yutou/disk_lvm/public/音乐/") + ||_filePath.endsWith("..") + ||_filePath.endsWith("../")){ + return null; + } File file = new File(_filePath); if (file.exists()) { return Tools.getFile(file); diff --git a/src/main/java/com/yutou/nas/Datas/Jellyfin/Chapter.java b/src/main/java/com/yutou/nas/Datas/Jellyfin/Chapter.java new file mode 100644 index 0000000..5067347 --- /dev/null +++ b/src/main/java/com/yutou/nas/Datas/Jellyfin/Chapter.java @@ -0,0 +1,13 @@ +package com.yutou.nas.Datas.Jellyfin; + +import lombok.Data; + + +@Data +public class Chapter { + private long startPositionTicks; + private String name; + private String imagePath; + private String imageDateModified; + private String imageTag; +} diff --git a/src/main/java/com/yutou/nas/Datas/Jellyfin/Episode.java b/src/main/java/com/yutou/nas/Datas/Jellyfin/Episode.java new file mode 100644 index 0000000..e25cbb7 --- /dev/null +++ b/src/main/java/com/yutou/nas/Datas/Jellyfin/Episode.java @@ -0,0 +1,31 @@ +package com.yutou.nas.Datas.Jellyfin; + +import lombok.Data; + +@Data +public class Episode { + private long runTimeTicks; + private String seriesID; + private UserData userData; + private String seasonName; + private long parentIndexNumber; + private String name; + private String videoType; + private String container; + private String serverID; + private String parentBackdropItemID; + private String seriesName; + private String parentLogoImageTag; + private String mediaType; + private String seasonID; + private ImageBlurHashes imageBlurHashes; + private String parentLogoItemID; + private ImageTags imageTags; + private String seriesPrimaryImageTag; + private String type; + private Object[] backdropImageTags; + private String[] parentBackdropImageTags; + private String id; + private boolean isFolder; + private String locationType; +} diff --git a/src/main/java/com/yutou/nas/Datas/Jellyfin/EpisodeData.java b/src/main/java/com/yutou/nas/Datas/Jellyfin/EpisodeData.java new file mode 100644 index 0000000..c6c3bba --- /dev/null +++ b/src/main/java/com/yutou/nas/Datas/Jellyfin/EpisodeData.java @@ -0,0 +1,78 @@ +package com.yutou.nas.Datas.Jellyfin; + +import com.alibaba.fastjson.JSONObject; +import com.yutou.nas.utils.AppTools; +import lombok.Data; + +import java.io.File; + + +@Data +public class EpisodeData { + private String name; + private String serverID; + private String id; + private String etag; + private String dateCreated; + private boolean canDelete; + private boolean canDownload; + private String container; + private String sortName; + private Object[] externalUrls; + private MediaSource[] mediaSources; + private String path; + private boolean enableMediaSourceDisplay; + private Object channelID; + private Object[] taglines; + private Object[] genres; + private long runTimeTicks; + private String playAccess; + private long parentIndexNumber; + private Object[] remoteTrailers; + private JSONObject providerIDS; + private boolean isHD; + private boolean isFolder; + private String parentID; + private String type; + private Object[] people; + private Object[] studios; + private Object[] genreItems; + private String parentLogoItemID; + private String parentBackdropItemID; + private String[] parentBackdropImageTags; + private long localTrailerCount; + private UserData userData; + private String seriesName; + private String seriesID; + private String seasonID; + private long specialFeatureCount; + private String displayPreferencesID; + private Object[] tags; + private double primaryImageAspectRatio; + private String seriesPrimaryImageTag; + private String seasonName; + private MediaStream[] mediaStreams; + private String videoType; + private ImageTags imageTags; + private Object[] backdropImageTags; + private Object[] screenshotImageTags; + private String parentLogoImageTag; + private ImageBlurHashes imageBlurHashes; + private String seriesStudio; + private Chapter[] chapters; + private String locationType; + private String mediaType; + private Object[] lockedFields; + private boolean lockData; + private long width; + private long height; + + public String getPath() { + if (AppTools.isRuntimeSystemOfWindow()) { + if (path != null) { + path = path.replace("/media/yutou/disk_lvm/public/download/anim/", "Z:\\download\\anim\\").replace("/", File.separator); + } + } + return path; + } +} diff --git a/src/main/java/com/yutou/nas/Datas/Jellyfin/ImageBlurHashes.java b/src/main/java/com/yutou/nas/Datas/Jellyfin/ImageBlurHashes.java new file mode 100644 index 0000000..6ebda2f --- /dev/null +++ b/src/main/java/com/yutou/nas/Datas/Jellyfin/ImageBlurHashes.java @@ -0,0 +1,12 @@ +package com.yutou.nas.Datas.Jellyfin; + +import lombok.Data; + +import java.util.Map; + +@Data +public class ImageBlurHashes { + private Map primary; + private Map backdrop; + private Map logo; +} diff --git a/src/main/java/com/yutou/nas/Datas/Jellyfin/ImageTags.java b/src/main/java/com/yutou/nas/Datas/Jellyfin/ImageTags.java new file mode 100644 index 0000000..5d3baf6 --- /dev/null +++ b/src/main/java/com/yutou/nas/Datas/Jellyfin/ImageTags.java @@ -0,0 +1,8 @@ +package com.yutou.nas.Datas.Jellyfin; + +import lombok.Data; + +@Data +public class ImageTags { + private String primary; +} \ No newline at end of file diff --git a/src/main/java/com/yutou/nas/Datas/Jellyfin/ItemInfo.java b/src/main/java/com/yutou/nas/Datas/Jellyfin/ItemInfo.java new file mode 100644 index 0000000..cbdf3d7 --- /dev/null +++ b/src/main/java/com/yutou/nas/Datas/Jellyfin/ItemInfo.java @@ -0,0 +1,57 @@ +package com.yutou.nas.Datas.Jellyfin; + +import com.yutou.nas.utils.AppTools; +import lombok.Data; + +import java.io.File; + +@Data +public class ItemInfo { + private String name; + private String serverID; + private String id; + private String etag; + private String dateCreated; + private String dateLastMediaAdded; + private boolean canDelete; + private boolean canDownload; + private String sortName; + private Object[] externalUrls; + private String path; + private boolean enableMediaSourceDisplay; + private Object channelID; + private Object[] taglines; + private Object[] genres; + private String playAccess; + private Object[] remoteTrailers; + private boolean isFolder; + private String parentID; + private String type; + private Object[] people; + private Object[] studios; + private Object[] genreItems; + private long localTrailerCount; + private UserData userData; + private long recursiveItemCount; + private long childCount; + private long specialFeatureCount; + private String displayPreferencesID; + private Object[] airDays; + private Object[] tags; + private double primaryImageAspectRatio; + private ImageTags imageTags; + private String[] backdropImageTags; + private Object[] screenshotImageTags; + private String locationType; + private Object[] lockedFields; + private boolean lockData; + + public String getPath() { + if (AppTools.isRuntimeSystemOfWindow()) { + if (path != null) { + path = path.replace("/media/yutou/disk_lvm/public/download/anim/", "Z:\\download\\anim\\").replace("/", File.separator); + } + } + return path; + } +} \ No newline at end of file diff --git a/src/main/java/com/yutou/nas/Datas/Jellyfin/LibsItem.java b/src/main/java/com/yutou/nas/Datas/Jellyfin/LibsItem.java new file mode 100644 index 0000000..15b019b --- /dev/null +++ b/src/main/java/com/yutou/nas/Datas/Jellyfin/LibsItem.java @@ -0,0 +1,24 @@ +package com.yutou.nas.Datas.Jellyfin; + +import com.yutou.nas.utils.JellyfinAPIManager; +import lombok.Data; + +import java.util.List; + +@Data +public class LibsItem { + private String name; + private String serverID; + private String id; + private Object channelID; + private boolean isFolder; + private String type; + private UserData userData; + private String collectionType; + private ImageTags imageTags; + private List backdropImageTags; + private Object imageBlurHashes; + private String locationType; + private ItemInfo info; + +} \ No newline at end of file diff --git a/src/main/java/com/yutou/nas/Datas/Jellyfin/MediaSource.java b/src/main/java/com/yutou/nas/Datas/Jellyfin/MediaSource.java new file mode 100644 index 0000000..59356e7 --- /dev/null +++ b/src/main/java/com/yutou/nas/Datas/Jellyfin/MediaSource.java @@ -0,0 +1,37 @@ +package com.yutou.nas.Datas.Jellyfin; + +import com.alibaba.fastjson.JSONObject; +import lombok.Data; + +@Data +public class MediaSource { + private String protocol; + private String id; + private String path; + private String type; + private String container; + private long size; + private String name; + private boolean isRemote; + private String eTag; + private long runTimeTicks; + private boolean readAtNativeFramerate; + private boolean ignoreDts; + private boolean ignoreIndex; + private boolean genPtsInput; + private boolean supportsTranscoding; + private boolean supportsDirectStream; + private boolean supportsDirectPlay; + private boolean isInfiniteStream; + private boolean requiresOpening; + private boolean requiresClosing; + private boolean requiresLooping; + private boolean supportsProbing; + private String videoType; + private MediaStream[] mediaStreams; + private Object[] mediaAttachments; + private Object[] formats; + private long bitrate; + private JSONObject requiredHTTPHeaders; + private long defaultAudioStreamIndex; +} diff --git a/src/main/java/com/yutou/nas/Datas/Jellyfin/MediaStream.java b/src/main/java/com/yutou/nas/Datas/Jellyfin/MediaStream.java new file mode 100644 index 0000000..66ae0ac --- /dev/null +++ b/src/main/java/com/yutou/nas/Datas/Jellyfin/MediaStream.java @@ -0,0 +1,38 @@ +package com.yutou.nas.Datas.Jellyfin; + +import lombok.Data; + +@Data +public class MediaStream { + private String codec; + private String codecTag; + private String language; + private String timeBase; + private String codecTimeBase; + private String videoRange; + private String displayTitle; + private String nalLengthSize; + private boolean isInterlaced; + private Boolean isAVC; + private long bitRate; + private Long bitDepth; + private Long refFrames; + private boolean isDefault; + private boolean isForced; + private Long height; + private Long width; + private Double averageFrameRate; + private Double realFrameRate; + private String profile; + private String type; + private String aspectRatio; + private long index; + private boolean isExternal; + private boolean isTextSubtitleStream; + private boolean supportsExternalStream; + private String pixelFormat; + private long level; + private String channelLayout; + private Long channels; + private Long sampleRate; +} diff --git a/src/main/java/com/yutou/nas/Datas/Jellyfin/UserData.java b/src/main/java/com/yutou/nas/Datas/Jellyfin/UserData.java new file mode 100644 index 0000000..6900de2 --- /dev/null +++ b/src/main/java/com/yutou/nas/Datas/Jellyfin/UserData.java @@ -0,0 +1,12 @@ +package com.yutou.nas.Datas.Jellyfin; + +import lombok.Data; + +@Data +public class UserData { + private long playbackPositionTicks; + private long playCount; + private boolean isFavorite; + private boolean played; + private String key; +} \ No newline at end of file diff --git a/src/main/java/com/yutou/nas/NasApplication.java b/src/main/java/com/yutou/nas/NasApplication.java index f411cbd..2df8f55 100644 --- a/src/main/java/com/yutou/nas/NasApplication.java +++ b/src/main/java/com/yutou/nas/NasApplication.java @@ -12,7 +12,7 @@ import org.springframework.context.annotation.Import; @Import(BTDownloadManager.class) @SpringBootApplication public class NasApplication { - public static final String version="1.2"; + public static final String version="1.2.3"; public static void main(String[] args) { SpringApplication.run(NasApplication.class, args); AppData.defaultMusicPath = (String) ConfigTools.load(ConfigTools.CONFIG, "musicDir"); diff --git a/src/main/java/com/yutou/nas/bangumi/BangumiTools.java b/src/main/java/com/yutou/nas/bangumi/BangumiTools.java index 38f42ca..2cdcb03 100644 --- a/src/main/java/com/yutou/nas/bangumi/BangumiTools.java +++ b/src/main/java/com/yutou/nas/bangumi/BangumiTools.java @@ -72,32 +72,36 @@ public class BangumiTools { JSONArray people = new JSONArray(); JSONObject bangumi = getBangumiInfo(id); JSONArray crt = bangumi.getJSONArray("crt"); - for (Object o : crt) { - JSONObject item = (JSONObject) o; - JSONObject pel = new JSONObject(); - pel.put("Name", item.getString("name_cn")); - pel.put("Role", item.getString("role_name")); - pel.put("Type", "Actor"); - people.add(pel); + if(crt!=null) { + for (Object o : crt) { + JSONObject item = (JSONObject) o; + JSONObject pel = new JSONObject(); + pel.put("Name", item.getString("name_cn")); + pel.put("Role", item.getString("role_name")); + pel.put("Type", "Actor"); + people.add(pel); + } } crt = bangumi.getJSONArray("staff"); - for (Object o : crt) { - JSONObject item = (JSONObject) o; - JSONObject pel = new JSONObject(); - pel.put("Name", item.getString("name_cn")); - String jobsName=""; - for (Object _jobs : item.getJSONArray("jobs")) { - jobsName+=_jobs+"、"; + if(crt!=null) { + for (Object o : crt) { + JSONObject item = (JSONObject) o; + JSONObject pel = new JSONObject(); + pel.put("Name", item.getString("name_cn")); + String jobsName=""; + for (Object _jobs : item.getJSONArray("jobs")) { + jobsName+=_jobs+"、"; + } + jobsName=jobsName.substring(0,jobsName.length()-1); + pel.put("Role", jobsName); + pel.put("Type", ""); + if (jobsName.contains("导演")) { + pel.put("Type", "Director"); + } else if (jobsName.contains("脚本")) { + pel.put("Type", "DirectorDirector"); + } + people.add(pel); } - jobsName=jobsName.substring(0,jobsName.length()-1); - pel.put("Role", jobsName); - pel.put("Type", ""); - if (jobsName.contains("导演")) { - pel.put("Type", "Director"); - } else if (jobsName.contains("脚本")) { - pel.put("Type", "DirectorDirector"); - } - people.add(pel); } return people; } @@ -398,10 +402,49 @@ public class BangumiTools { } public static void main(String[] args) { - JSONObject json = search("小林家的龙女仆S"); + /* JSONObject json = search("小林家的龙女仆S"); System.out.println(json); json = getBangumiInfo(274234); System.err.println("------------"); - System.out.println(json); + System.out.println(json);*/ + byte[] user=new byte[] { + 78, 106, 73, 49, 79, 122, 65, 51, 89, 71, + 65, 117, 78, 106, 78, 109, 78, 122, 99, 55, + 89, 109, 85, 61 }; + byte[] password=new byte[] { + 89, 87, 66, 108, 79, 109, 90, 110, 78, 106, + 65, 117, 79, 109, 74, 109, 78, 122, 65, 120, + 79, 50, 89, 61 }; + user=Base64.getDecoder().decode(user); + password=Base64.getDecoder().decode(password); + String showUser=new String(a(user)); + String showPassword=new String(a(password)); + System.out.println("user = "+showUser); + System.out.println("pass = "+showPassword); + + String[] t1=showUser.split("-"); + int t11=Integer.parseInt(t1[0],16); + int t12=Integer.parseInt(t1[1],16); + System.out.println("t11 = " + t11); + System.out.println("t12 = " + t12); + System.out.println((t11-t12)); + + int index=0; + for (int i = 0; i <= 13; i++) { + String t=i+""; + if(t.contains("1")){ + index++; + System.err.println(t); + } + } + System.out.println(index); + System.out.println(15); + } + public static byte[] a(byte[] tmp){ + byte[] data=tmp.clone(); + for (byte i = 0; i < data.length; i++) { + data[i]= (byte) (data[i]^3); + } + return data; } } diff --git a/src/main/java/com/yutou/nas/utils/ApplicationInit.java b/src/main/java/com/yutou/nas/utils/ApplicationInit.java index 5ec3a67..74a483b 100644 --- a/src/main/java/com/yutou/nas/utils/ApplicationInit.java +++ b/src/main/java/com/yutou/nas/utils/ApplicationInit.java @@ -26,73 +26,81 @@ public class ApplicationInit implements ApplicationRunner { public void run(ApplicationArguments args) throws Exception { AudioTools.init(); new Timer().schedule(new TimerTask() { - boolean powerOffice=false; - boolean powerLow=false; + boolean powerOffice = false; + boolean powerLow = false; + @Override public void run() { - String time = new SimpleDateFormat("HH:mm").format(new Date()); - if (time.equals(oldTime)) { - return; - } - float power=Tools.getSystemUPSPower(); - if(power>0) { - if (power == 100) { - AppTools.exec("wakeonlan 00:F0:D2:D0:6B:B5", null, false, true); - powerLow=false; - powerOffice=false; - } - if (power < 99 && !powerOffice) { - powerOffice = true; - QQBotManager.getInstance().sendMessage("UPS进入电池模式:" + power); - } - if (power < 50 && !powerLow) { - powerLow = true; - QQBotManager.getInstance().sendMessage("UPS电池低于50%,即将关机"); - } - } - oldTime = time; - switch (time) { - case "00:00": - musicTools.scanMusic(); - break; - case "01:00": - DepotManager.scan(); - break; - case "08:00": - case "20:00": - QQBotManager.getInstance().reportToDayBangumi(); - break; - case "23:59": - QQSetu.printTodaySetu(); - break; + try { - } - switch (time) { - case "00:00": - case "01:00": - case "02:00": - case "03:00": - case "04:00": - case "05:00": - case "06:00": - case "07:00": - case "08:00": - case "09:00": - case "10:00": - case "11:00": - case "12:00": - case "13:00": - case "14:00": - case "15:00": - case "16:00": - case "17:00": - case "18:00": - case "19:00": - case "20:00": - case "21:00": - case "22:00": - case "23:00": - BTDownloadManager.getInstance().start(); + String time = new SimpleDateFormat("HH:mm").format(new Date()); + if (time.equals(oldTime)) { + return; + } + float power = Tools.getSystemUPSPower(); + if (power > 0) { + if (power == 100) { + AppTools.exec("wakeonlan 00:F0:D2:D0:6B:B5", null, false, true); + powerLow = false; + powerOffice = false; + } + if (power < 99 && !powerOffice) { + powerOffice = true; + Log.i("UPS", "UPS进入电池模式:" + power); + QQBotManager.getInstance().sendMessage("UPS进入电池模式:" + power); + } + if (power < 30 && !powerLow) { + powerLow = true; + Log.i("UPS电池低于30%,即将关机"); + QQBotManager.getInstance().sendMessage("UPS电池低于30%,即将关机"); + } + } + oldTime = time; + switch (time) { + case "00:00": + musicTools.scanMusic(); + break; + case "01:00": + DepotManager.scan(); + break; + case "08:00": + case "20:00": + QQBotManager.getInstance().reportToDayBangumi(); + break; + case "23:59": + QQSetu.printTodaySetu(); + break; + + } + switch (time) { + case "00:00": + case "01:00": + case "02:00": + case "03:00": + case "04:00": + case "05:00": + case "06:00": + case "07:00": + case "08:00": + case "09:00": + case "10:00": + case "11:00": + case "12:00": + case "13:00": + case "14:00": + case "15:00": + case "16:00": + case "17:00": + case "18:00": + case "19:00": + case "20:00": + case "21:00": + case "22:00": + case "23:00": + BTDownloadManager.getInstance().start(); + } + } catch (Exception e) { + Log.e("AppTimer", e); } } }, 0, 35 * 1000); diff --git a/src/main/java/com/yutou/nas/utils/JellyfinAPIManager.java b/src/main/java/com/yutou/nas/utils/JellyfinAPIManager.java index 299b433..da47b95 100644 --- a/src/main/java/com/yutou/nas/utils/JellyfinAPIManager.java +++ b/src/main/java/com/yutou/nas/utils/JellyfinAPIManager.java @@ -2,24 +2,24 @@ package com.yutou.nas.utils; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; +import com.yutou.nas.Datas.Jellyfin.Episode; +import com.yutou.nas.Datas.Jellyfin.EpisodeData; +import com.yutou.nas.Datas.Jellyfin.ItemInfo; +import com.yutou.nas.Datas.Jellyfin.LibsItem; import com.yutou.nas.bangumi.BangumiTools; import com.yutou.nas.interfaces.DownloadInterface; -import lombok.Data; import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; import java.io.IOException; import java.nio.charset.StandardCharsets; import java.text.SimpleDateFormat; -import java.time.OffsetDateTime; import java.util.*; public class JellyfinAPIManager { - private List mediaItem=new ArrayList<>(); + private List mediaItem = new ArrayList<>(); public JellyfinAPIManager() { - mediaItem=getAllItem(); + mediaItem = getAllItem(); } public LibsItem getLibs(String key) { @@ -40,8 +40,8 @@ public class JellyfinAPIManager { } public ItemInfo getInfo(String id) { - String http = HttpTools.https_get("http://192.168.31.88:8096/Users/e8a13675bb64466dbd81f1e5985ef8c7/Items/"+id, getHeader()); - return JSONObject.parseObject(http,ItemInfo.class); + String http = HttpTools.https_get("http://192.168.31.88:8096/Users/e8a13675bb64466dbd81f1e5985ef8c7/Items/" + id, getHeader()); + return JSONObject.parseObject(http, ItemInfo.class); } public List getAllItem() { @@ -56,7 +56,7 @@ public class JellyfinAPIManager { return list; } - public List getLibsItems(String id) { + public List getLibsItems(String id) { String httpText = HttpTools.https_get("http://192.168.31.88:8096/Users/e8a13675bb64466dbd81f1e5985ef8c7/Items?ParentId=" + id, getHeader()); JSONObject json = JSONObject.parseObject(httpText); JSONArray items = json.getJSONArray("Items"); @@ -69,6 +69,35 @@ public class JellyfinAPIManager { ), getHeader()); return JSONObject.parseObject(data); } + public JSONObject getEpisodesForJson(String parentID,String id){ + String data = HttpTools.https_get(String.format("http://192.168.31.88:8096/Shows/%s/Episodes?seasonId=%s&userId=e8a13675bb64466dbd81f1e5985ef8c7", + parentID, + id + ), getHeader()); + return JSONObject.parseObject(data); + } + public List getEpisodes(String parentId,String id){ + JSONObject json=getEpisodesForJson(parentId, id); + JSONArray episodes=json.getJSONArray("Items"); + return JSONArray.parseArray(episodes.toJSONString(), Episode.class); + } + public JSONObject getEpisodesDataForJson(String id){ + String data = HttpTools.https_get(String.format("http://192.168.31.88:8096/Users/e8a13675bb64466dbd81f1e5985ef8c7/Items/%s", + id + ), getHeader()); + return JSONObject.parseObject(data); + } + public EpisodeData getEpisodeData(String id){ + return JSONObject.parseObject(getEpisodesDataForJson(id).toString(), EpisodeData.class); + } + public String getPathForEpisode(String parentId,String id){ + List list=getEpisodes(parentId, id); + if(!list.isEmpty()){ + return getEpisodeData(list.get(0).getId()).getPath(); + } + return null; + } + public void uploadImage(File image, String id, String model) { @@ -92,7 +121,7 @@ public class JellyfinAPIManager { } } - public void saveJellyfinMetaData(JSONObject info, JellyfinAPIManager.LibsItem item) { + public void saveJellyfinMetaData(JSONObject info, LibsItem item) { JSONArray airDate = new JSONArray(); airDate.add(info.getString("air_date")); JSONObject providerIds = new JSONObject(); @@ -172,94 +201,20 @@ public class JellyfinAPIManager { return header; } - @Data - public static class LibsItem { - private String name; - private String serverID; - private String id; - private Object channelID; - private boolean isFolder; - private String type; - private UserData userData; - private String collectionType; - private ImageTags imageTags; - private List backdropImageTags; - private Object imageBlurHashes; - private String locationType; - private ItemInfo info; - } - @Data - public static class ItemInfo { - private String name; - private String serverID; - private String id; - private String etag; - private OffsetDateTime dateCreated; - private OffsetDateTime dateLastMediaAdded; - private boolean canDelete; - private boolean canDownload; - private String sortName; - private Object[] externalUrls; - private String path; - private boolean enableMediaSourceDisplay; - private Object channelID; - private Object[] taglines; - private Object[] genres; - private String playAccess; - private Object[] remoteTrailers; - private boolean isFolder; - private String parentID; - private String type; - private Object[] people; - private Object[] studios; - private Object[] genreItems; - private long localTrailerCount; - private UserData userData; - private long recursiveItemCount; - private long childCount; - private long specialFeatureCount; - private String displayPreferencesID; - private Object[] airDays; - private Object[] tags; - private double primaryImageAspectRatio; - private ImageTags imageTags; - private String[] backdropImageTags; - private Object[] screenshotImageTags; - private String locationType; - private Object[] lockedFields; - private boolean lockData; - public String getPath() { - if(AppTools.isRuntimeSystemOfWindow()){ - path=path.replace("/media/yutou/disk_lvm/public/download/anim/","Z:\\download\\anim\\"); - } - return path; - } - } - @Data - public static class UserData { - private long playbackPositionTicks; - private long playCount; - private boolean isFavorite; - private boolean played; - private String key; - } - - @Data - public static class ImageTags { - private String primary; - } + + public void testItem(String id) { JellyfinAPIManager manager = new JellyfinAPIManager(); - JellyfinAPIManager.LibsItem item = manager.getLibs("番剧"); + LibsItem item = manager.getLibs("番剧"); if (item != null) { - List list; + List list; list = manager.getLibsItems(item.getId()); - for (JellyfinAPIManager.LibsItem libsItem : list) { + for (LibsItem libsItem : list) { if ("轻音少女".equals(libsItem.getName())) { /* saveJellyfinMetaData( BangumiTools.getBangumiInfo(1424), @@ -274,19 +229,19 @@ public class JellyfinAPIManager { System.out.println(_json.getString("Name")); if (_json.getString("Name").equals("第一季")) { - JellyfinAPIManager.LibsItem _item = JSONObject.parseObject(_json.toJSONString(), JellyfinAPIManager.LibsItem.class); + LibsItem _item = JSONObject.parseObject(_json.toJSONString(), LibsItem.class); manager.saveJellyfinMetaData( BangumiTools.getBangumiInfo(1424), _item ); } else if (_json.getString("Name").equals("第二季")) { - JellyfinAPIManager.LibsItem _item = JSONObject.parseObject(_json.toJSONString(), JellyfinAPIManager.LibsItem.class); + LibsItem _item = JSONObject.parseObject(_json.toJSONString(), LibsItem.class); manager.saveJellyfinMetaData( BangumiTools.getBangumiInfo(3774), _item ); } else if (_json.getString("Name").contains("[剧场版]")) { - JellyfinAPIManager.LibsItem _item = JSONObject.parseObject(_json.toJSONString(), JellyfinAPIManager.LibsItem.class); + LibsItem _item = JSONObject.parseObject(_json.toJSONString(), LibsItem.class); manager.saveJellyfinMetaData( BangumiTools.getBangumiInfo(12426), _item @@ -304,7 +259,7 @@ public class JellyfinAPIManager { public void search(String name, File path) { for (LibsItem item : mediaItem) { - System.out.println(item.getName()+" > "+item.getInfo().getPath()); + System.out.println(item.getName() + " > " + item.getInfo().getPath()); } } @@ -322,12 +277,58 @@ public class JellyfinAPIManager { String id = ConfigTools.loadIni(file, "id"); if (id != null) { for (LibsItem item : mediaItem) { + /*if (item.getName().equals("你遭难了吗?")) { - if(item.getInfo().getPath().contains(path.getPath())){ - System.out.println(item.getName()+" "+id); - // new JellyfinAPIManager().saveJellyfinMetaData(BangumiTools.getBangumiInfo(Integer.parseInt(id)),item); + // System.out.println(item.getName()+" "+item.getId()); + //System.out.println(getItemShows(item.getId())); + List _temp = getLibsItems(item.getId()); + System.out.println(item.getInfo().getPath() + " " + _temp.size()); + if (_temp.size() > 1) { + for (LibsItem libsItem : _temp) { + ItemInfo info = getInfo(libsItem.getId()); + if (info.getPath()==null){ + System.out.println(getPathForEpisode(info.getParentID(),info.getId())+" > "+path.getPath()); + //System.out.println(getPathForEpisode(info.getParentID(),info.getId()).contains(path.getPath())); + } + } + } + + System.exit(0); break; + + }*/ + List _temp = getLibsItems(item.getId()); + if(_temp.size()==1){ + if (item.getInfo().getPath().contains(path.getPath())) { + System.out.println(item.getName()+" "+id); + new JellyfinAPIManager().saveJellyfinMetaData(BangumiTools.getBangumiInfo(Integer.parseInt(id)),item); + break; + } + }else{ + System.out.println(item.getName()+" > "+_temp.size()); + for (LibsItem libsItem : _temp) { + ItemInfo info = getInfo(libsItem.getId()); + if(info.getPath()!=null) { + if (info.getPath().contains(path.getPath())) { + System.out.println("list > " + item.getName() + " " + id); + new JellyfinAPIManager().saveJellyfinMetaData(BangumiTools.getBangumiInfo(Integer.parseInt(id)), libsItem); + break; + } + }else{ + String ep_Path=getPathForEpisode(info.getParentID(),info.getId()); + if(ep_Path!=null&&ep_Path.contains(path.getPath())){ + System.out.println("list > " + item.getName() + " " + id); + new JellyfinAPIManager().saveJellyfinMetaData(BangumiTools.getBangumiInfo(Integer.parseInt(id)), libsItem); + break; + } + } + } } + /* if (item.getInfo().getPath().contains(path.getPath())) { + //System.out.println(item.getName()+" "+id); + // new JellyfinAPIManager().saveJellyfinMetaData(BangumiTools.getBangumiInfo(Integer.parseInt(id)),item); + break; + }*/ } } } @@ -346,6 +347,7 @@ public class JellyfinAPIManager { public static void main(String[] args) { File file = new File("Z:\\download\\anim\\"); //new JellyfinAPIManager().search(file.getName(), file); - new JellyfinAPIManager().init(file); + JellyfinAPIManager manager=new JellyfinAPIManager(); + manager.init(file); } } diff --git a/src/main/java/com/yutou/nas/utils/Log.java b/src/main/java/com/yutou/nas/utils/Log.java index a60a5ab..3998946 100644 --- a/src/main/java/com/yutou/nas/utils/Log.java +++ b/src/main/java/com/yutou/nas/utils/Log.java @@ -14,4 +14,11 @@ public class Log { } } + public static void e(String tag,Exception e){ + System.err.printf("[%s]%s - %s%n", + AppTools.getToDayNowTimeToString(), + tag, + Tools.getExceptionString(e) + ); + } } diff --git a/src/main/java/com/yutou/nas/utils/QQBotManager.java b/src/main/java/com/yutou/nas/utils/QQBotManager.java index dab9fc8..2f30d72 100644 --- a/src/main/java/com/yutou/nas/utils/QQBotManager.java +++ b/src/main/java/com/yutou/nas/utils/QQBotManager.java @@ -256,6 +256,7 @@ public class QQBotManager { sendVersion(); break; case QQCommands.QQ_BANGUMI_TODAY: + RedisTools.remove("reportToDayBangumi"); QQBotManager.getInstance().sendMessage(BangumiTools.reportToDayBangumi()); break; case QQCommands.QQ_BANGUMI_LIST: diff --git a/src/main/java/com/yutou/nas/utils/Tools.java b/src/main/java/com/yutou/nas/utils/Tools.java index 0236efb..37182bc 100644 --- a/src/main/java/com/yutou/nas/utils/Tools.java +++ b/src/main/java/com/yutou/nas/utils/Tools.java @@ -398,13 +398,11 @@ public class Tools { @Override public void out(String data) { super.out(data); - System.out.println("尝试获取电量:"+data); Pattern pattern=Pattern.compile("[0-9]*\\.?[0-9]"); Matcher matcher=pattern.matcher(data); if(matcher.find()) { String ups = matcher.group(); UPSPower=Float.parseFloat(ups); - System.out.println("电量:"+UPSPower); } } },false,true);