├── .github └── workflows │ ├── build.yml │ └── release.yml ├── .gitignore ├── .gitmodules ├── LICENSE ├── LICENSE0 ├── LICENSE1 ├── LICENSE_MPLv2 ├── Makefile ├── README.md ├── containers └── builder │ ├── Dockerfile │ └── Makefile ├── history.md ├── libs ├── NativeApplicationUpdater-0.5.1.swc ├── airhttpd-0.5-mineap-0.1.swc └── flashlsOSMF.swc ├── nndd-5ch_certificate.pfx ├── src ├── CategoryList.json ├── ConnectionStatusView.mxml ├── JumpDialog.mxml ├── LoadWindow.mxml ├── LoginDialog.mxml ├── Makefile ├── MyListEditDialog.mxml ├── NNDD-app.xml ├── NNDD.mxml ├── NNDDUpdaterWindow.mxml ├── NameEditDialog.mxml ├── NicoCommentViewer-app.xml ├── NicoCommentViewer.mxml ├── ScheduleWindow.mxml ├── SearchItemEdit.mxml ├── TagTileListRenderer.mxml ├── VideoController.mxml ├── VideoEditDialog.mxml ├── VideoInfoView.mxml ├── VideoPlayer.mxml ├── VideoSourceSelectWindow.mxml ├── config │ └── updateConfig.xml ├── icon128.png ├── icon16.png ├── icon32.png ├── icon48.png ├── org │ ├── libspark │ │ └── utils │ │ │ └── ForcibleLoader.as │ └── mineap │ │ ├── nInterpreter │ │ ├── IAnalyzeResult.as │ │ ├── NInterpreter.as │ │ ├── ResultType.as │ │ ├── ScriptLine.as │ │ ├── instance │ │ │ ├── CommentDefaultOptionManager.as │ │ │ └── JumpMarkerManager.as │ │ ├── nico2niwa │ │ │ └── operation │ │ │ │ ├── Nico2NiwaConverter.as │ │ │ │ ├── jump │ │ │ │ └── JumpComverter.as │ │ │ │ ├── jumpmarker │ │ │ │ ├── JumpMarker.as │ │ │ │ └── JumpMarkerConverter.as │ │ │ │ └── setdefault │ │ │ │ └── DefaultComverter.as │ │ └── operation │ │ │ ├── IOperationAnalyzer.as │ │ │ ├── addMarker │ │ │ ├── AddMarkerOperationAnalyzer.as │ │ │ └── AddMarkerResult.as │ │ │ ├── comment │ │ │ └── color │ │ │ │ └── CommentColorOperationAnalyzer.as │ │ │ ├── getMarker │ │ │ ├── GetMarkerOperationAnalyzer.as │ │ │ └── GetMarkerResult.as │ │ │ ├── jump │ │ │ ├── JumpOperationAnalyzer.as │ │ │ └── JumpResult.as │ │ │ └── seek │ │ │ ├── SeekOperationAnalyzer.as │ │ │ └── SeekResult.as │ │ ├── nicovideo4as │ │ ├── nndd │ │ ├── Access2Nico.as │ │ ├── FileIO.as │ │ ├── LogManager.as │ │ ├── Message.as │ │ ├── NNDD.as │ │ ├── NNDDDownloader.as │ │ ├── NNDDMyListAdder.as │ │ ├── NNDDMyListLoader.as │ │ ├── NNDDMyListsLoader.as │ │ ├── NNDDSearchListRenewer.as │ │ ├── NNDDVideoPageWatcher.as │ │ ├── RenewDownloadManager.as │ │ ├── SystemTrayIconManager.as │ │ ├── download │ │ │ ├── DownloadManager.as │ │ │ ├── DownloadStatusType.as │ │ │ └── ScheduleManager.as │ │ ├── downloadedList │ │ │ └── DownloadedListManager.as │ │ ├── event │ │ │ ├── LibraryLoadEvent.as │ │ │ ├── LocalCommentSearchEvent.as │ │ │ └── MyListRenewProgressEvent.as │ │ ├── history │ │ │ └── HistoryManager.as │ │ ├── library │ │ │ ├── ILibraryManager.as │ │ │ ├── LibraryDirSearchUtil.as │ │ │ ├── LibraryManagerBuilder.as │ │ │ ├── LibraryTreeBuilder.as │ │ │ ├── LocalVideoInfoLoader.as │ │ │ ├── namedarray │ │ │ │ ├── LibraryXMLHelper.as │ │ │ │ └── NamedArrayLibraryManager.as │ │ │ └── sqlite │ │ │ │ ├── DbAccessHelper.as │ │ │ │ ├── Queries.as │ │ │ │ ├── SQLiteLibraryManager.as │ │ │ │ ├── dao │ │ │ │ ├── FileDao.as │ │ │ │ ├── NNDDVideoDao.as │ │ │ │ ├── NNDDVideoTagStringDao.as │ │ │ │ ├── TagStringDao.as │ │ │ │ └── VersionDao.as │ │ │ │ └── util │ │ │ │ └── DbMigrationUtil.as │ │ ├── model │ │ │ ├── DownloadQueueItem.as │ │ │ ├── MyListRenewResultType.as │ │ │ ├── MyListSortType.as │ │ │ ├── NNDDComment.as │ │ │ ├── NNDDFile.as │ │ │ ├── NNDDSearchSortType.as │ │ │ ├── NNDDSearchType.as │ │ │ ├── NNDDVideo.as │ │ │ ├── NicoVideoRSS.as │ │ │ ├── PlayList.as │ │ │ ├── RssType.as │ │ │ ├── Schedule.as │ │ │ ├── SearchItem.as │ │ │ ├── SearchSortString.as │ │ │ ├── SearchTypeString.as │ │ │ ├── TagString.as │ │ │ ├── VideoType.as │ │ │ └── tree │ │ │ │ ├── ITreeItem.as │ │ │ │ ├── TreeFileItem.as │ │ │ │ └── TreeFolderItem.as │ │ ├── myList │ │ │ ├── MyList.as │ │ │ ├── MyListBuilder.as │ │ │ ├── MyListHistoryManager.as │ │ │ ├── MyListManager.as │ │ │ ├── MyListRenewScheduler.as │ │ │ ├── MyListTreeItemRenderer.mxml │ │ │ └── NNDDMyListGroupLoader.as │ │ ├── nativeProcessPlayer │ │ │ └── NativeProcessPlayerManager.as │ │ ├── playList │ │ │ ├── PlayListAnalyzer.as │ │ │ ├── PlayListDataGridBuilder.as │ │ │ └── PlayListManager.as │ │ ├── player │ │ │ ├── NGListManager.as │ │ │ ├── PatchedVideoDisplay.as │ │ │ ├── PlayerController.as │ │ │ ├── PlayerHistoryManager.as │ │ │ ├── PlayerManager.as │ │ │ ├── PlayerMylistAddr.as │ │ │ ├── comment │ │ │ │ ├── Command.as │ │ │ │ ├── CommentManager.as │ │ │ │ └── Comments.as │ │ │ └── model │ │ │ │ └── PlayerTagString.as │ │ ├── ranking │ │ │ └── RankingListBuilder.as │ │ ├── search │ │ │ └── SearchItemManager.as │ │ ├── server │ │ │ ├── GetVideoDataProcess.as │ │ │ ├── IRequestProcess.as │ │ │ ├── NNDDHttpService.as │ │ │ ├── RequestProcessFactory.as │ │ │ ├── RequestType.as │ │ │ ├── ResponseType.as │ │ │ ├── ServerManager.as │ │ │ └── process │ │ │ │ ├── GetMyListByIdProcess.as │ │ │ │ ├── GetMyListProcess.as │ │ │ │ ├── GetVideoByIdProcess.as │ │ │ │ └── GetVideoIdListProcess.as │ │ ├── tag │ │ │ ├── NgTagManager.as │ │ │ └── TagManager.as │ │ ├── user │ │ │ └── UserManager.as │ │ ├── util │ │ │ ├── CategoryUtil.as │ │ │ ├── ConfFileUtil.as │ │ │ ├── DataGridColumnWidthUtil.as │ │ │ ├── DateUtil.as │ │ │ ├── LibraryUtil.as │ │ │ ├── LogUtil.as │ │ │ ├── MyListUtil.as │ │ │ ├── NNDDThumbInfoAnalyzer.as │ │ │ ├── NicoPattern.as │ │ │ ├── NicoServerStatusCheck.as │ │ │ ├── NumberUtil.as │ │ │ ├── PathMaker.as │ │ │ ├── RankingStringBuilder.as │ │ │ ├── RelationTypeUtil.as │ │ │ ├── ShortUrlChecker.as │ │ │ ├── ThumbInfoAnalyzer.as │ │ │ ├── ThumbInfoUtil.as │ │ │ ├── TreeDataBuilder.as │ │ │ ├── TreeItemUtil.as │ │ │ ├── VideoPrefix.as │ │ │ └── WebServiceAccessUtil.as │ │ ├── versionCheck │ │ │ ├── IVersionChecker.as │ │ │ ├── VersionChecker.as │ │ │ ├── VersionCheckerFactory.as │ │ │ ├── VersionCheckerForNativeApplication.as │ │ │ └── VersionUtil.as │ │ └── view │ │ │ ├── LoadingPicture.as │ │ │ ├── LoginDialog.as │ │ │ ├── NNDDText.as │ │ │ ├── SmoothImage.as │ │ │ ├── UpdateDialog.as │ │ │ ├── VideoController.as │ │ │ ├── VideoEditDialog.as │ │ │ ├── VideoInfoView.as │ │ │ └── VideoPlayer.as │ │ └── util │ │ ├── config │ │ ├── ConfUtil.as │ │ ├── ConfigIO.as │ │ └── ConfigManager.as │ │ └── font │ │ └── FontUtil.as └── player │ ├── NNDDicons_pause_20x20.png │ ├── NNDDicons_play_20x20.png │ └── NNDDicons_stop_20x20.png ├── update_v2_native.xml └── utils └── category_list_update ├── fetch_ranking_genre_tags.ts ├── package-lock.json └── package.json /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | name: build 2 | on: 3 | push: 4 | branches: 5 | - master 6 | paths: 7 | - libs/** 8 | - src/** 9 | - nicovideo4as 10 | workflow_dispatch: 11 | jobs: 12 | build-air: 13 | runs-on: ubuntu-latest 14 | env: 15 | AIR_HOME: /opt/airsdk 16 | steps: 17 | - uses: actions/checkout@v4 18 | with: 19 | submodules: recursive 20 | 21 | - uses: actions/cache@v4 22 | id: apache_flex_cache 23 | with: 24 | path: apache-flex-sdk-4.16.1-bin.tar.gz 25 | key: https://dlcdn.apache.org/flex/4.16.1/binaries/apache-flex-sdk-4.16.1-bin.tar.gz 26 | - if: steps.apache_flex_cache.outputs.cache-hit != 'true' 27 | run: curl https://dlcdn.apache.org/flex/4.16.1/binaries/apache-flex-sdk-4.16.1-bin.tar.gz -O 28 | 29 | - uses: actions/cache@v4 30 | id: adobe_airsdk_cache 31 | with: 32 | path: AdobeAIRSDK.zip 33 | key: http://fpdownload.macromedia.com/air/win/download/32.0/AdobeAIRSDK.zip 34 | enableCrossOsArchive: true 35 | - if: steps.adobe_airsdk_cache.outputs.cache-hit != 'true' 36 | run: curl http://fpdownload.macromedia.com/air/win/download/32.0/AdobeAIRSDK.zip -O 37 | 38 | - uses: actions/cache@v4 39 | id: flex_osmf20_cache 40 | with: 41 | path: OSMF2_0.swc 42 | key: https://sourceforge.net/adobe/flexsdk/code/HEAD/tree/trunk/frameworks/libs/OSMF2_0.swc?format=raw 43 | - if: steps.flex_osmf20_cache.outputs.cache-hit != 'true' 44 | run: curl https://sourceforge.net/adobe/flexsdk/code/HEAD/tree/trunk/frameworks/libs/OSMF2_0.swc?format=raw -o OSMF2_0.swc 45 | 46 | - name: setup 47 | run: | 48 | tar xzf apache-flex-sdk-4.16.1-bin.tar.gz 49 | mv apache-flex-sdk-4.16.1-bin $AIR_HOME 50 | unzip AdobeAIRSDK.zip -d $AIR_HOME 51 | cp OSMF2_0.swc $AIR_HOME/frameworks/libs/osmf.swc 52 | 53 | - name: build 54 | run: | 55 | cd src 56 | $AIR_HOME/bin/amxmlc NNDD.mxml -compiler.include-libraries ../libs/* -warnings=false 57 | java -jar $AIR_HOME/lib/adt.jar -certificate -cn SelfSigned 2048-RSA certificate_no_password.pfx '' 58 | java -jar $AIR_HOME/lib/adt.jar -package -storetype pkcs12 -keystore certificate_no_password.pfx -storepass '' NNDD.air NNDD-app.xml NNDD.swf icon32.png icon128.png icon48.png icon16.png CategoryList.json 59 | 60 | - uses: actions/upload-artifact@v4 61 | with: 62 | name: air 63 | path: src/NNDD.air 64 | 65 | build-exe: 66 | needs: build-air 67 | runs-on: windows-latest 68 | steps: 69 | - uses: actions/download-artifact@v4 70 | with: 71 | name: air 72 | 73 | - uses: actions/cache@v4 74 | id: adobe_airsdk_cache 75 | with: 76 | path: AdobeAIRSDK.zip 77 | key: http://fpdownload.macromedia.com/air/win/download/32.0/AdobeAIRSDK.zip 78 | enableCrossOsArchive: true 79 | - if: steps.adobe_airsdk_cache.outputs.cache-hit != 'true' 80 | run: curl http://fpdownload.macromedia.com/air/win/download/32.0/AdobeAIRSDK.zip -O 81 | 82 | - name: setup 83 | shell: bash 84 | run: | 85 | unzip AdobeAIRSDK.zip -d air 86 | 87 | - name: build 88 | run: | 89 | air/bin/adt.bat -package -target native NNDD.exe NNDD.air 90 | 91 | - uses: actions/upload-artifact@v4 92 | with: 93 | name: exe 94 | path: NNDD.exe 95 | 96 | build-dmg: 97 | needs: build-air 98 | runs-on: macos-latest 99 | steps: 100 | - uses: actions/download-artifact@v4 101 | with: 102 | name: air 103 | 104 | - uses: actions/cache@v4 105 | id: adobe_airsdk_cache 106 | with: 107 | path: AdobeAIRSDK.dmg 108 | key: https://airdownload.adobe.com/air/mac/download/32.0/AdobeAIRSDK.dmg 109 | - if: steps.adobe_airsdk_cache.outputs.cache-hit != 'true' 110 | run: curl https://airdownload.adobe.com/air/mac/download/32.0/AdobeAIRSDK.dmg -O 111 | 112 | - name: setup 113 | run: | 114 | hdiutil mount AdobeAIRSDK.dmg 115 | ditto '/Volumes/AIR SDK' air 116 | 117 | - name: build 118 | run: | 119 | air/bin/adt -package -target native NNDD.dmg NNDD.air 120 | 121 | - uses: actions/upload-artifact@v4 122 | with: 123 | name: dmg 124 | path: NNDD.dmg 125 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ### JetBrains template 2 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm 3 | # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 4 | 5 | # User-specific stuff: 6 | .idea/**/workspace.xml 7 | .idea/**/tasks.xml 8 | .idea/dictionaries 9 | 10 | # Sensitive or high-churn files: 11 | .idea/**/dataSources/ 12 | .idea/**/dataSources.ids 13 | .idea/**/dataSources.xml 14 | .idea/**/dataSources.local.xml 15 | .idea/**/sqlDataSources.xml 16 | .idea/**/dynamic.xml 17 | .idea/**/uiDesigner.xml 18 | 19 | # Gradle: 20 | .idea/**/gradle.xml 21 | .idea/**/libraries 22 | 23 | # Mongo Explorer plugin: 24 | .idea/**/mongoSettings.xml 25 | 26 | ## File-based project format: 27 | *.iws 28 | 29 | ## Plugin-specific files: 30 | 31 | # IntelliJ 32 | /out/ 33 | 34 | # mpeltonen/sbt-idea plugin 35 | .idea_modules/ 36 | 37 | # JIRA plugin 38 | atlassian-ide-plugin.xml 39 | 40 | # Crashlytics plugin (for Android Studio and IntelliJ) 41 | com_crashlytics_export_strings.xml 42 | crashlytics.properties 43 | crashlytics-build.properties 44 | fabric.properties 45 | ### Actionscript template 46 | # Build and Release Folders 47 | bin/ 48 | bin-debug/ 49 | bin-release/ 50 | [Oo]bj/ # FlashDevelop obj 51 | [Bb]in/ # FlashDevelop bin 52 | 53 | # Other files and folders 54 | .settings/ 55 | 56 | # Executables 57 | *.swf 58 | *.air 59 | *.ipa 60 | *.apk 61 | 62 | # Project files, i.e. `.project`, `.actionScriptProperties` and `.flexProperties` 63 | # should NOT be excluded as they contain compiler settings and other important 64 | # information for Eclipse / Flash Builder. 65 | ### Windows template 66 | # Windows thumbnail cache files 67 | Thumbs.db 68 | ehthumbs.db 69 | ehthumbs_vista.db 70 | 71 | # Folder config file 72 | Desktop.ini 73 | 74 | # Recycle Bin used on file shares 75 | $RECYCLE.BIN/ 76 | 77 | # Windows Installer files 78 | *.cab 79 | *.msi 80 | *.msm 81 | *.msp 82 | 83 | # Windows shortcuts 84 | *.lnk 85 | ### macOS template 86 | *.DS_Store 87 | .AppleDouble 88 | .LSOverride 89 | 90 | # Icon must end with two \r 91 | Icon 92 | 93 | 94 | # Thumbnails 95 | ._* 96 | 97 | # Files that might appear in the root of a volume 98 | .DocumentRevisions-V100 99 | .fseventsd 100 | .Spotlight-V100 101 | .TemporaryItems 102 | .Trashes 103 | .VolumeIcon.icns 104 | .com.apple.timemachine.donotpresent 105 | 106 | # Directories potentially created on remote AFP share 107 | .AppleDB 108 | .AppleDesktop 109 | Network Trash Folder 110 | Temporary Items 111 | .apdisk 112 | 113 | .idea/ 114 | *.p12 115 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "nicovideo4as"] 2 | path = nicovideo4as 3 | url = https://github.com/nndd-reboot/nicovideo4as.git 4 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 nndd-reboot (https://github.com/nndd-reboot) 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /LICENSE0: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2008 MineAP (https://ja.osdn.net/projects/nndd/) 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /LICENSE1: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 SSW-SCIENTIFIC 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: build with-docker builder-img pathcheck certificate-arg-check certificate certificate-with-docker help 2 | .DEFAULT_GOAL=help 3 | 4 | build: ## NNDD.air をビルドします 5 | @cd src && make build 6 | 7 | with-docker: ## Dockerコンテナを使って NNDD.air をビルドします 8 | @cd src && make with-docker 9 | 10 | builder-img: ## NNDDビルド用のDockerイメージをビルドします 11 | @cd containers/builder && make build 12 | 13 | pathcheck: 14 | @if [ -z "$$AIR_HOME" ]; then \ 15 | echo 'AIR_HOMEが設定されてないよ。'; \ 16 | echo '末尾に"/"が付かないように指定してね。'; \ 17 | echo; \ 18 | exit 1; \ 19 | fi 20 | 21 | certificate-arg-check: 22 | @if [ -z "$$name" ] || [ -z "$$pass" ]; then \ 23 | echo 'ファイル名とパスワードを指定してね。'; \ 24 | echo 'Usage: make certificate name=[ファイル名] pass=[パスワード]'; \ 25 | echo; \ 26 | exit 1; \ 27 | fi 28 | 29 | certificate: pathcheck certificate-arg-check ## ビルドに必要な証明書を作成します 30 | @java -jar $$AIR_HOME/lib/adt.jar -certificate -cn SelfSigned 2048-RSA "$$name" "$$pass" 31 | 32 | certificate-with-docker: certificate-arg-check ## Dockerコンテナを使ってビルドに必要な証明書を作成します 33 | @docker run --rm -it -v $$(pwd):/root/NNDD nndd-builder /bin/sh -c "cd /root/NNDD && make certificate name='$$name' pass='$$pass'" 34 | 35 | help: ## このヘルプを表示します 36 | @grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' 37 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # NNDD 5chメンテナンス版(NNDD-5ch) 2 | 3 | 本ソフトウェアは[MineAP][]さんが作成された[NNDD][] ver2.4.3からフォークした[NNDD+DMC][] ver4.0.1からフォークしたソフトウェアです。 4 | 5 | 本プロジェクトでリリースしたNNDD-5ch (version >= 4.1.0)を利用して発生した不具合等に関しては[このリポジトリのIssues][Issues]、5ch [NNDDスレ][5ch nndd]、またはDiscord [NNDD 5chサーバ][discord nndd]にご報告いただくようお願いします。 6 | **オリジナルの作者様にお問い合わせをすることのないようにお願いします。** 7 | 8 | ## 現在分かっている不具合 9 | _人人人人人人人人人人人人人人人人人人_ 10 | >  コメントの投稿ができない!!  < 11 |  ̄Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y ̄ 12 | 13 | ## このソフトウェアについて 14 | NNDD-5chは[ニコニコ動画](http://www.nicovideo.jp)にアップロードされた動画の視聴およびダウンロード/管理をするための自由ソフトウェアです。 15 | 16 | 動画の視聴, 保存に加え, ランキングの表示や動画の検索, マイリストの管理を行うことが出来ます。 17 | 18 | ## 対応環境 19 | Windows用インストーラ(.exe)及びmacOS用イメージ(.dmg), どちらでも利用可能なAIRパッケージ(.air)の3種類をリリースしています。 20 | メンテナの環境はWindowsであるため, メインストリームはWindows, 詳細なバグ報告等が頂ければmacOSでも対応を検討するというスタンスです。 21 | 22 | 尚, Linux上で動作する報告もあり, メンテナも手元で確認しましたが, Linuxについては質問やバグ報告等頂いても**一切対応しません**。 23 | 手元で動作させた状況のみWiki [(参考) Linuxへのインストール][NNDD+DMC on Linux] に記述しましたので, これ以上は必要であれば各自でご対応下さい。 24 | 25 | ## ダウンロード 26 | 最新版のダウンロードは[**こちら (releases/latest)**][Release-Latest]から行ってください。 27 | 28 | Windows用インストーラ(.exe)及びmacOS用イメージ(.dmg)でインストールした場合には, 設定から「起動時にバージョンチェックをする」にチェックを入れている場合(デフォルト)には起動時に最新バージョンの確認及びインストールが可能です。 29 | 30 | 新機能追加や大幅な修正等の際には自動アップデートの対象にならないバージョン(Alpha版)のリリースを行います。 31 | これらのバージョンをご利用の際には[Releases][]のページからご希望のバージョンをダウンロード/インストールしてご利用下さい。 32 | 不具合等ありましたら[Issues][]にご報告頂けると有り難いです。 33 | 34 | 35 | ## NNDD+DMCからの設定の引継ぎ 36 | NNDD-5chでは, NNDD+DMCと異なる場所に設定ファイルが保存されます。 37 | NNDD+DMCから設定を引き継ぎたい場合にはNNDD+DMC Wikiの[**NNDDからNNDD DMCへの設定の引継ぎについて**][Config]をご覧ください。 38 | 基本的な手順はNNDDからNNDD+DMCへの引継ぎと同じです。 39 | NNDD-5chのディレクトリのパスは\[org.mineap.nndd-5ch\]です。 40 | 41 | ## ライセンス 42 | 本ソフトウェアは[MITライセンス][License]の下で公開, 頒布される自由ソフトウェアです。 43 | ライセンスに示された利用条件に同意する限り, 本ソフトウェアは用途を問わず誰でも自由に利用することが出来ます。 44 | 45 | MITライセンスに示されるとおり, 本ソフトウェアは**無保証**です。 46 | 作者及び著作権者は, 本ソフトウェアに起因し, または関わる事柄に関して一切の責任及び義務を負うことは無いものとします。 47 | 48 | ライセンスの詳細は本リポジトリの[LICENSE][License]ファイルをご確認下さい。 49 | 50 | ## 謝辞 51 | [NNDD][]作者の[MineAP][]氏, 並びに下記ライブラリの作者に対してこの場を借りて御礼申し上げます。 52 | 53 | * [NNDD][] © MineAP (MIT License ([LICENCE0][License-Orig])) 54 | * [nicovideo4as][NNDD] © MineAP (MIT License ([LICENSE0][License-Orig])) 55 | * [AirHttpd][NNDD] © MineAP (MIT License ([LICENSE0][License-Orig])) 56 | * [NativeApplicationUpdater][] © Piotr Walczyszyn (Apache License 2.0) 57 | * [Flashls][] © [mangui][] ([Mozilla Public License 2.0][MPLv2]) 58 | 59 | ## 協力者募集! 60 | 協力してもいいよ!という方はお気軽にDiscord [NNDD 5chサーバ][discord nndd]にご参加ください。 61 | 62 | [MineAP]: https://twitter.com/mineap 63 | [NNDD]: https://ja.osdn.net/projects/nndd/ 64 | [NNDD+DMC]: https://github.com/SSW-SCIENTIFIC/NNDD 65 | [Issues]: https://github.com/nndd-reboot/NNDD/issues 66 | [License]: https://github.com/nndd-reboot/NNDD/blob/master/LICENSE 67 | [License-Orig]: https://github.com/nndd-reboot/NNDD/blob/master/LICENSE0 68 | [MPLv2]: https://github.com/nndd-reboot/NNDD/blob/master/LICENSE_MPLv2 69 | [NativeApplicationUpdater]: https://code.google.com/archive/p/nativeapplicationupdater/ 70 | [Flashls]: http://www.flashls.org/ 71 | [mangui]: https://github.com/mangui 72 | [Config]: https://github.com/SSW-SCIENTIFIC/NNDD/wiki/NNDD%E3%81%8B%E3%82%89NNDD-DMC%E3%81%B8%E3%81%AE%E8%A8%AD%E5%AE%9A%E3%81%AE%E5%BC%95%E7%B6%99%E3%81%8E%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6 73 | [NNDD+DMC on Linux]: https://github.com/SSW-SCIENTIFIC/NNDD/wiki/(%E5%8F%82%E8%80%83)-Linux%E3%81%B8%E3%81%AE%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB 74 | [Release-Latest]: https://github.com/nndd-reboot/NNDD/releases/latest 75 | [Releases]: https://github.com/nndd-reboot/NNDD/releases 76 | [5ch nndd]: https://egg.5ch.net/test/read.cgi/software/1701226145/l50 77 | [discord nndd]: https://discord.gg/KhkyjwuJRh 78 | -------------------------------------------------------------------------------- /containers/builder/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM alpine:latest 2 | 3 | RUN apk update && apk add openjdk11-jre-headless make 4 | 5 | ADD apache-flex-sdk-4.16.1-bin.tar.gz /root/ 6 | RUN mv /root/apache-flex-sdk-4.16.1-bin /opt/airsdk 7 | 8 | COPY AdobeAIRSDK.zip /root/ 9 | RUN unzip /root/AdobeAIRSDK.zip -d /opt/airsdk 10 | RUN rm /root/AdobeAIRSDK.zip 11 | 12 | COPY OSMF2_0.swc /opt/airsdk/frameworks/libs/osmf.swc 13 | 14 | ENV AIR_HOME=/opt/airsdk PATH=/opt/airsdk/bin:$PATH 15 | -------------------------------------------------------------------------------- /containers/builder/Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: all build download build-with-squash 2 | .DEFAULT_GOAL=build 3 | 4 | build: download 5 | @echo 'コンテナをビルドします' 6 | @docker build . -t nndd-builder:latest 7 | 8 | build-with-squash: download 9 | @echo 'コンテナをビルドします' 10 | @docker build . -t nndd-builder:latest --squash 11 | 12 | download: apache-flex-sdk-4.16.1-bin.tar.gz AdobeAIRSDK.zip OSMF2_0.swc 13 | 14 | apache-flex-sdk-4.16.1-bin.tar.gz: 15 | @echo 'Apache Flex SDKをダウンロードします' 16 | @curl https://dlcdn.apache.org/flex/4.16.1/binaries/apache-flex-sdk-4.16.1-bin.tar.gz -O 17 | @echo 18 | 19 | AdobeAIRSDK.zip: 20 | @echo 'Adobe AIR SDKをダウンロードします' 21 | @curl http://fpdownload.macromedia.com/air/win/download/32.0/AdobeAIRSDK.zip -O 22 | @echo 23 | 24 | OSMF2_0.swc: 25 | @echo 'osmfライブラリをダウンロードします' 26 | @curl https://sourceforge.net/adobe/flexsdk/code/HEAD/tree/trunk/frameworks/libs/OSMF2_0.swc?format=raw -o OSMF2_0.swc 27 | @echo 28 | -------------------------------------------------------------------------------- /libs/NativeApplicationUpdater-0.5.1.swc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nndd-reboot/NNDD/cd15e326435cf8428f75e8de173981673d1f57b0/libs/NativeApplicationUpdater-0.5.1.swc -------------------------------------------------------------------------------- /libs/airhttpd-0.5-mineap-0.1.swc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nndd-reboot/NNDD/cd15e326435cf8428f75e8de173981673d1f57b0/libs/airhttpd-0.5-mineap-0.1.swc -------------------------------------------------------------------------------- /libs/flashlsOSMF.swc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nndd-reboot/NNDD/cd15e326435cf8428f75e8de173981673d1f57b0/libs/flashlsOSMF.swc -------------------------------------------------------------------------------- /nndd-5ch_certificate.pfx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nndd-reboot/NNDD/cd15e326435cf8428f75e8de173981673d1f57b0/nndd-5ch_certificate.pfx -------------------------------------------------------------------------------- /src/JumpDialog.mxml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /src/LoadWindow.mxml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: build pathcheck with-docker help 2 | .DEFAULT_GOAL=help 3 | 4 | build: NNDD.air ## NNDD.air をビルドします 5 | 6 | pathcheck: 7 | @if [ -z "$$AIR_HOME" ]; then \ 8 | echo 'AIR_HOMEが設定されてないよ。'; \ 9 | echo '末尾に"/"が付かないように指定してね。'; \ 10 | echo; \ 11 | exit 1; \ 12 | fi 13 | 14 | NNDD.air: pathcheck NNDD.swf 15 | @java -jar $$AIR_HOME/lib/adt.jar -certificate -cn SelfSigned 2048-RSA certificate_no_password.pfx '' 16 | @java -jar $$AIR_HOME/lib/adt.jar -package -storetype pkcs12 -keystore certificate_no_password.pfx -storepass '' NNDD.air NNDD-app.xml NNDD.swf icon32.png icon128.png icon48.png icon16.png CategoryList.json 17 | 18 | NNDD.swf: pathcheck 19 | @$$AIR_HOME/bin/amxmlc NNDD.mxml -compiler.include-libraries ../libs/* -warnings=false 20 | 21 | with-docker: ## Dockerコンテナを使って NNDD.air をビルドします 22 | @docker run --rm -it -v $$(cd ../ && pwd):/root/NNDD nndd-builder /bin/sh -c 'cd /root/NNDD/src && make build' 23 | 24 | help: ## このヘルプを表示します 25 | @grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' 26 | -------------------------------------------------------------------------------- /src/MyListEditDialog.mxml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 8 | 9 | 10 | = 1) { 38 | 39 | if (getIsDir() == true || textInput_url.text.length >= 1) { 40 | 41 | this._name = textInput_name.text; 42 | this._url = textInput_url.text; 43 | 44 | dispatchEvent(new Event(Event.COMPLETE)); 45 | } 46 | } 47 | } 48 | 49 | private function editCancelButtonClicked(): void { 50 | PopUpManager.removePopUp(this); 51 | } 52 | 53 | /** 54 | * 55 | */ 56 | private function comboBox_isFolder_changeHandler(event: ListEvent): void { 57 | if (ComboBox(event.currentTarget).selectedIndex == 0) { 58 | label_url.enabled = false; 59 | textInput_url.enabled = false; 60 | } else { 61 | label_url.enabled = true; 62 | textInput_url.enabled = true; 63 | } 64 | } 65 | 66 | /** 67 | * 68 | */ 69 | public function getIsDir(): Boolean { 70 | 71 | if (comboBox_isFolder.selectedIndex == 0) { 72 | return true; 73 | } else { 74 | return false; 75 | } 76 | 77 | } 78 | 79 | /** 80 | * このマイリスト項目がディレクトリを表すかどうかを 81 | */ 82 | public function setDir(isDir: Boolean): void { 83 | if (isDir) { 84 | comboBox_isFolder.selectedIndex = 0; 85 | label_url.enabled = false; 86 | textInput_url.enabled = false; 87 | } else { 88 | comboBox_isFolder.selectedIndex = 1; 89 | label_url.enabled = true; 90 | textInput_url.enabled = true; 91 | } 92 | } 93 | 94 | /** 95 | * TextInputにフォーカスが移った際のイベントハンドラです 96 | */ 97 | protected function textInputfocusInHandler(event: FocusEvent): void { 98 | TextInput(event.currentTarget).selectionBeginIndex = 0; 99 | TextInput(event.currentTarget).selectionEndIndex = TextInput(event.currentTarget).text.length; 100 | } 101 | ]]> 102 | 103 | 104 | 105 | 106 | 108 | 109 | 110 | 111 | 112 | 114 | 115 | 116 | 117 | 118 | 120 | 121 | 122 | 123 | 125 | 126 | 127 | 128 | 129 | 130 | -------------------------------------------------------------------------------- /src/TagTileListRenderer.mxml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /src/VideoController.mxml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 12 | 13 | 14 | 15 | 17 | 19 | 20 | 21 | 27 | 28 | 29 | 30 | 31 | 32 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /src/VideoEditDialog.mxml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 14 | 15 | 16 | 17 | 18 | 19 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 32 | 33 | 34 | 35 | 36 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /src/config/updateConfig.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | http://sourceforge.jp/projects/nndd/wiki/Version/attach/update_v2_air.xml 4 | 1 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /src/icon128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nndd-reboot/NNDD/cd15e326435cf8428f75e8de173981673d1f57b0/src/icon128.png -------------------------------------------------------------------------------- /src/icon16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nndd-reboot/NNDD/cd15e326435cf8428f75e8de173981673d1f57b0/src/icon16.png -------------------------------------------------------------------------------- /src/icon32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nndd-reboot/NNDD/cd15e326435cf8428f75e8de173981673d1f57b0/src/icon32.png -------------------------------------------------------------------------------- /src/icon48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nndd-reboot/NNDD/cd15e326435cf8428f75e8de173981673d1f57b0/src/icon48.png -------------------------------------------------------------------------------- /src/org/mineap/nInterpreter/IAnalyzeResult.as: -------------------------------------------------------------------------------- 1 | package org.mineap.nInterpreter { 2 | public interface IAnalyzeResult { 3 | 4 | function get resultType(): ResultType; 5 | 6 | } 7 | } -------------------------------------------------------------------------------- /src/org/mineap/nInterpreter/NInterpreter.as: -------------------------------------------------------------------------------- 1 | package org.mineap.nInterpreter { 2 | 3 | 4 | /** 5 | * 6 | * @author shiraminekeisuke 7 | * 8 | */ 9 | public class NInterpreter { 10 | 11 | public static const SEPARATE_PATTERN: RegExp = new RegExp("[([^;]*);?]+"); 12 | 13 | /** 14 | * 15 | * 16 | */ 17 | public function NInterpreter() { 18 | /* 何もしない */ 19 | } 20 | 21 | /** 22 | * 渡された命令を解析し、解析結果を返します。 23 | * 24 | * @param source "/"で始まるニワン語、もしくは"@"で始まるニコスクリプト 25 | * @return 解析結果 26 | * 27 | */ 28 | public function analyze(source: String): IAnalyzeResult { 29 | 30 | var firstChar: String = source.charAt(0); 31 | 32 | if (firstChar == "/") { 33 | 34 | 35 | //命令を分割 36 | var array: Array = separate(source); 37 | 38 | 39 | //中に式が入りうる命令 40 | //commentTrigger 41 | //ctrig 42 | //if 43 | //alternative 44 | 45 | 46 | } else if (firstChar == "@" || firstChar == "@") { 47 | 48 | 49 | } 50 | 51 | } 52 | 53 | /** 54 | * 渡された命令列を";"で区切って分割します。 55 | * @param source 56 | * @return 命令文字列を格納したArray 57 | * 58 | */ 59 | public function separate(source: String): Array { 60 | 61 | // a=true;if(a,then:dt(a,pos:'hidari')) 62 | var results: Array = SEPARATE_PATTERN.exec(source); 63 | var array: Array = new Array(); 64 | 65 | if (results != null && results.length > 0) { 66 | for (var i: int = 1; i < results.length; i++) { 67 | array.push(results[i]); 68 | } 69 | } 70 | 71 | return array; 72 | } 73 | 74 | 75 | } 76 | } -------------------------------------------------------------------------------- /src/org/mineap/nInterpreter/ResultType.as: -------------------------------------------------------------------------------- 1 | package org.mineap.nInterpreter { 2 | /** 3 | * 4 | * @author shiraminekeisuke(MineAP) 5 | * 6 | */ 7 | public class ResultType { 8 | public function ResultType() { 9 | } 10 | 11 | /** 12 | * jump命令の解析結果である事を示す定数です。 13 | */ 14 | public static const JUMP: ResultType = new ResultType(); 15 | 16 | /** 17 | * seek命令の解析結果である事を示す定数です。 18 | */ 19 | public static const SEEK: ResultType = new ResultType(); 20 | 21 | /** 22 | * addMarker命令の解析結果である事を示す定数です。 23 | */ 24 | public static const ADD_MARKER: ResultType = new ResultType(); 25 | 26 | /** 27 | * getMarker命令の解析結果である事を示す定数です。 28 | */ 29 | public static const GET_MARKER: ResultType = new ResultType(); 30 | 31 | } 32 | } -------------------------------------------------------------------------------- /src/org/mineap/nInterpreter/ScriptLine.as: -------------------------------------------------------------------------------- 1 | package org.mineap.nInterpreter { 2 | /** 3 | * 実行するスクリプト1行を表現するデータモデル 4 | * 5 | * @author shiraminekeisuke(MineAP) 6 | * 7 | */ 8 | public class ScriptLine { 9 | 10 | private var _line: String; 11 | 12 | private var _mail: String; 13 | 14 | private var _vpos: int; 15 | 16 | /** 17 | * 18 | * @param line 19 | * @param mail 20 | * @param vpos 21 | * 22 | */ 23 | public function ScriptLine(line: String, mail: String, vpos: int) { 24 | this._line = line; 25 | this._mail = mail; 26 | this._vpos = vpos; 27 | } 28 | 29 | public function get mail(): String { 30 | return _mail; 31 | } 32 | 33 | public function set mail(value: String): void { 34 | _mail = value; 35 | } 36 | 37 | /** 38 | * 実際のスクリプト文字列 39 | */ 40 | public function get line(): String { 41 | return _line; 42 | } 43 | 44 | /** 45 | * スクリプトが実行された時刻(vpos) 46 | */ 47 | public function get vpos(): int { 48 | return _vpos; 49 | } 50 | 51 | /** 52 | * 53 | * @param value 54 | * 55 | */ 56 | public function set line(value: String): void { 57 | _line = value; 58 | } 59 | 60 | /** 61 | * 62 | * @param value 63 | * 64 | */ 65 | public function set vpos(value: int): void { 66 | _vpos = value; 67 | } 68 | 69 | 70 | } 71 | } -------------------------------------------------------------------------------- /src/org/mineap/nInterpreter/instance/CommentDefaultOptionManager.as: -------------------------------------------------------------------------------- 1 | package org.mineap.nInterpreter.instance { 2 | /** 3 | * コメントのデフォルト設定(色、位置、大きさなど)を保持するクラスです。 4 | * 5 | * @author shiraminekeisuke (MineAP) 6 | * 7 | */ 8 | public class CommentDefaultOptionManager { 9 | 10 | private static const manager: CommentDefaultOptionManager = new CommentDefaultOptionManager(); 11 | 12 | private var defaultColor: int = int(0xffffff); 13 | 14 | public function CommentDefaultOptionManager() { 15 | if (manager != null) { 16 | throw new ArgumentError("CommentDefaultOptionManagerはインスタンス化できません."); 17 | } 18 | } 19 | 20 | /** 21 | * 22 | * @return 23 | * 24 | */ 25 | public static function get instance(): CommentDefaultOptionManager { 26 | return CommentDefaultOptionManager.manager; 27 | } 28 | 29 | /** 30 | * 31 | * 32 | */ 33 | public function initalize(): void { 34 | defaultColor = int(0xffffff); 35 | } 36 | 37 | /** 38 | * 39 | * @param color 40 | * 41 | */ 42 | public function set commentColor(color: int): void { 43 | this.defaultColor = color; 44 | } 45 | 46 | /** 47 | * 48 | * @return 49 | * 50 | */ 51 | public function get commentColor(): int { 52 | return this.defaultColor; 53 | } 54 | 55 | 56 | } 57 | } -------------------------------------------------------------------------------- /src/org/mineap/nInterpreter/instance/JumpMarkerManager.as: -------------------------------------------------------------------------------- 1 | package org.mineap.nInterpreter.instance { 2 | import org.mineap.nInterpreter.nico2niwa.operation.jumpmarker.JumpMarker; 3 | 4 | /** 5 | * 6 | * @author shiraminekeisuke 7 | * 8 | */ 9 | public class JumpMarkerManager { 10 | 11 | private static const manager: JumpMarkerManager = new JumpMarkerManager(); 12 | 13 | private var markerName_vpos_map: Object = new Object(); 14 | 15 | /** 16 | * 17 | * @return 18 | * 19 | */ 20 | public static function get instance(): JumpMarkerManager { 21 | return manager; 22 | } 23 | 24 | public function JumpMarkerManager() { 25 | if (manager != null) { 26 | throw new ArgumentError("JumpMarkerMangerはインスタンス化できません"); 27 | } 28 | } 29 | 30 | /** 31 | * 32 | * 33 | */ 34 | public function initalize(): void { 35 | this.markerName_vpos_map = new Object(); 36 | } 37 | 38 | /** 39 | * 指定されたマーカにvposを対応づけてマーカを記憶します。 40 | * 41 | * @param marker 42 | * @param vpos 43 | * @return 44 | */ 45 | public function addMarker(marker: String, vpos: int): Boolean { 46 | if (marker == null) { 47 | return false; 48 | } 49 | 50 | var jumpMarker: JumpMarker = new JumpMarker(marker, vpos); 51 | 52 | trace("マーカを追加:" + marker + ", " + vpos); 53 | this.markerName_vpos_map[marker] = jumpMarker; 54 | 55 | return true; 56 | } 57 | 58 | /** 59 | * マーカに登録されているvposを取得します。vposが登録されていない時は-1を返します。 60 | * 61 | * @param marker 62 | * @return 63 | * 64 | */ 65 | public function getMarker(marker: String): int { 66 | if (marker == null) { 67 | return -1; 68 | } 69 | 70 | var object: Object = this.markerName_vpos_map[marker]; 71 | if (object == null) { 72 | return -1; 73 | } 74 | 75 | if (object is JumpMarker) { 76 | var vpos: int = (object as JumpMarker).vpos; 77 | trace("マーカを取得:" + marker + ", " + vpos); 78 | return vpos; 79 | } else { 80 | return -1; 81 | } 82 | 83 | } 84 | 85 | /** 86 | * 登録済みのJumpMarkerの一覧を返します 87 | * 88 | * @return 89 | * 90 | */ 91 | public function get markers(): Vector. { 92 | var jumpMarkers: Vector. = new Vector.(); 93 | 94 | trace("マーカ一覧を取得"); 95 | 96 | for each(var object: Object in this.markerName_vpos_map) { 97 | if (object is JumpMarker) { 98 | var name: String = (object as JumpMarker).marker; 99 | var vpos: int = (object as JumpMarker).vpos; 100 | trace("マーカ:" + name + ", " + vpos); 101 | jumpMarkers.push(object); 102 | } 103 | } 104 | 105 | return jumpMarkers; 106 | 107 | } 108 | 109 | } 110 | } -------------------------------------------------------------------------------- /src/org/mineap/nInterpreter/nico2niwa/operation/Nico2NiwaConverter.as: -------------------------------------------------------------------------------- 1 | package org.mineap.nInterpreter.nico2niwa.operation { 2 | import org.mineap.nInterpreter.ScriptLine; 3 | 4 | public interface Nico2NiwaConverter { 5 | function convert(source: ScriptLine): ScriptLine; 6 | } 7 | } -------------------------------------------------------------------------------- /src/org/mineap/nInterpreter/nico2niwa/operation/jumpmarker/JumpMarker.as: -------------------------------------------------------------------------------- 1 | package org.mineap.nInterpreter.nico2niwa.operation.jumpmarker { 2 | public class JumpMarker { 3 | private var _marker: String = null; 4 | 5 | private var _vpos: Number = 0; 6 | 7 | public function JumpMarker(marker: String, vpos: Number) { 8 | this._marker = marker; 9 | this._vpos = vpos; 10 | } 11 | 12 | public function get marker(): String { 13 | return _marker; 14 | } 15 | 16 | public function get vpos(): Number { 17 | return _vpos; 18 | } 19 | 20 | 21 | } 22 | } -------------------------------------------------------------------------------- /src/org/mineap/nInterpreter/nico2niwa/operation/jumpmarker/JumpMarkerConverter.as: -------------------------------------------------------------------------------- 1 | package org.mineap.nInterpreter.nico2niwa.operation.jumpmarker { 2 | import org.mineap.nInterpreter.ScriptLine; 3 | import org.mineap.nInterpreter.nico2niwa.operation.Nico2NiwaConverter; 4 | 5 | /** 6 | * 7 | * @author shiraminekeisuke 8 | * 9 | */ 10 | public class JumpMarkerConverter implements Nico2NiwaConverter { 11 | public function JumpMarkerConverter() { 12 | } 13 | 14 | /** 15 | * 次のニコスクリプトを解析する正規表現です。 16 | * "@ジャンプマーカー;ループ" 17 | * このジャンプマーカが実行された時刻が、マーカ"ループ"として登録されます。 18 | */ 19 | public static const JUMP_MARKER_OPERATION_PATTERN1: RegExp = new RegExp("ジャンプマーカー[:|:]([\\S]+)"); 20 | 21 | /** 22 | * 23 | * @param source 24 | * @return 25 | * 26 | */ 27 | public function convert(source: ScriptLine): ScriptLine { 28 | var line: String = source.line; 29 | var operation: String = ""; 30 | 31 | var array: Array = null; 32 | array = JUMP_MARKER_OPERATION_PATTERN1.exec(line); 33 | 34 | if (array != null && array.length > 0) { 35 | var marker: String = array[1]; 36 | 37 | if (marker != null) { 38 | operation = "addMarker(name:'" + marker + "',vpos:'" + source.vpos + "')"; 39 | } 40 | 41 | } 42 | 43 | return new ScriptLine(operation, source.mail, source.vpos); 44 | } 45 | 46 | } 47 | } -------------------------------------------------------------------------------- /src/org/mineap/nInterpreter/nico2niwa/operation/setdefault/DefaultComverter.as: -------------------------------------------------------------------------------- 1 | package org.mineap.nInterpreter.nico2niwa.operation.setdefault { 2 | import org.mineap.nInterpreter.ScriptLine; 3 | import org.mineap.nInterpreter.nico2niwa.operation.Nico2NiwaConverter; 4 | import org.mineap.nndd.player.comment.Command; 5 | 6 | public class DefaultComverter implements Nico2NiwaConverter { 7 | 8 | /** 9 | * @デフォルト命令を解析する正規表現です。 10 | */ 11 | public var DEFAULT_PATTERN: RegExp = new RegExp("デフォルト"); 12 | 13 | private static const command: Command = new Command(); 14 | 15 | public function DefaultComverter() { 16 | } 17 | 18 | /** 19 | * デフォルト命令をニワン語に変換します。 20 | * (現在は色設定のみ対応) 21 | * 22 | * @param source 23 | * @return 24 | * 25 | */ 26 | public function convert(source: ScriptLine): ScriptLine { 27 | var operation: String = ""; 28 | var line: String = source.line; 29 | var resultArray: Array = DEFAULT_PATTERN.exec(line); 30 | 31 | if (resultArray != null && resultArray.length > 0) { 32 | 33 | var color: int = command.getColorByCommand(source.mail); 34 | 35 | var colorStr: String = color.toString(16); 36 | while (colorStr.length < 6) { 37 | colorStr = "0" + colorStr; 38 | } 39 | 40 | operation = "commentColor=0x" + colorStr; 41 | 42 | } 43 | return new ScriptLine(operation, null, source.vpos); 44 | } 45 | } 46 | } -------------------------------------------------------------------------------- /src/org/mineap/nInterpreter/operation/IOperationAnalyzer.as: -------------------------------------------------------------------------------- 1 | package org.mineap.nInterpreter.operation { 2 | import org.mineap.nInterpreter.IAnalyzeResult; 3 | import org.mineap.nInterpreter.ScriptLine; 4 | 5 | public interface IOperationAnalyzer { 6 | 7 | function analyze(source: ScriptLine): IAnalyzeResult; 8 | 9 | } 10 | } -------------------------------------------------------------------------------- /src/org/mineap/nInterpreter/operation/addMarker/AddMarkerOperationAnalyzer.as: -------------------------------------------------------------------------------- 1 | package org.mineap.nInterpreter.operation.addMarker { 2 | import org.mineap.nInterpreter.IAnalyzeResult; 3 | import org.mineap.nInterpreter.ScriptLine; 4 | import org.mineap.nInterpreter.operation.IOperationAnalyzer; 5 | 6 | public class AddMarkerOperationAnalyzer implements IOperationAnalyzer { 7 | 8 | public static const ADD_MARKER_OPERATION_PATTERN_1: RegExp = new RegExp( 9 | "addMarker\\(name:['\"]([^,]+)['\"],vpos:['\"]([^\\)]+)['\"]\\)"); 10 | 11 | public function AddMarkerOperationAnalyzer() { 12 | } 13 | 14 | /** 15 | * 16 | * @param source 17 | * @return 18 | * 19 | */ 20 | public function analyze(source: ScriptLine): IAnalyzeResult { 21 | 22 | //addMarker(name:名前,vpos:時刻) 23 | 24 | var result: AddMarkerResult = null; 25 | var resultArray: Array = null; 26 | var line: String = source.line; 27 | 28 | resultArray = ADD_MARKER_OPERATION_PATTERN_1.exec(line); 29 | if (resultArray != null && resultArray.length > 0) { 30 | result = new AddMarkerResult(); 31 | result.name = String(resultArray[1]); 32 | result.vpos = Number(resultArray[2]); 33 | } 34 | 35 | return result; 36 | } 37 | } 38 | } -------------------------------------------------------------------------------- /src/org/mineap/nInterpreter/operation/addMarker/AddMarkerResult.as: -------------------------------------------------------------------------------- 1 | package org.mineap.nInterpreter.operation.addMarker { 2 | import org.mineap.nInterpreter.IAnalyzeResult; 3 | import org.mineap.nInterpreter.ResultType; 4 | 5 | /** 6 | * addMarker命令の解析結果を格納するクラスです 7 | * 8 | * @author shiraminekeisuke(MineAP) 9 | * 10 | */ 11 | public class AddMarkerResult implements IAnalyzeResult { 12 | /** 13 | * マーカの名前 14 | */ 15 | public var name: String; 16 | 17 | /** 18 | * マーカに指定された時刻(vpos) 19 | */ 20 | public var vpos: Number; 21 | 22 | /** 23 | * 24 | * 25 | */ 26 | public function AddMarkerResult() { 27 | // addMaker(name:名前,vpos:マーカー時刻) 28 | } 29 | 30 | /** 31 | * 32 | * @return 33 | * 34 | */ 35 | public function get resultType(): ResultType { 36 | return ResultType.ADD_MARKER; 37 | } 38 | 39 | } 40 | } -------------------------------------------------------------------------------- /src/org/mineap/nInterpreter/operation/comment/color/CommentColorOperationAnalyzer.as: -------------------------------------------------------------------------------- 1 | package org.mineap.nInterpreter.operation.comment.color { 2 | import org.mineap.nInterpreter.IAnalyzeResult; 3 | import org.mineap.nInterpreter.ScriptLine; 4 | import org.mineap.nInterpreter.instance.CommentDefaultOptionManager; 5 | import org.mineap.nInterpreter.operation.IOperationAnalyzer; 6 | 7 | public class CommentColorOperationAnalyzer implements IOperationAnalyzer { 8 | 9 | /** 10 | * 11 | */ 12 | public static const COMMENT_COLOR_OPERATION_PATTERN: RegExp = new RegExp( 13 | "commentColor=(0x[A-Fa-f0-9][A-Fa-f0-9][A-Fa-f0-9][A-Fa-f0-9][A-Fa-f0-9][A-Fa-f0-9])"); 14 | 15 | /** 16 | * 17 | * 18 | */ 19 | public function CommentColorOperationAnalyzer() { 20 | } 21 | 22 | /** 23 | * 渡された文字列を解析します。 24 | * この実装は結果を返さず、CommentDefaultOptionManagerに値を設定します。 25 | * 26 | * @param source 27 | * @return 28 | * 29 | */ 30 | public function analyze(source: ScriptLine): IAnalyzeResult { 31 | 32 | //commentColor=0xff0000 33 | 34 | //デフォルト値は 0xffffff 35 | 36 | var line: String = source.line; 37 | 38 | var resultArray: Array = null; 39 | resultArray = COMMENT_COLOR_OPERATION_PATTERN.exec(line); 40 | 41 | if (resultArray != null && resultArray.length > 0) { 42 | 43 | var color: int = int(resultArray[1]); 44 | 45 | CommentDefaultOptionManager.instance.commentColor = color; 46 | } 47 | 48 | return null; 49 | } 50 | 51 | } 52 | } -------------------------------------------------------------------------------- /src/org/mineap/nInterpreter/operation/getMarker/GetMarkerOperationAnalyzer.as: -------------------------------------------------------------------------------- 1 | package org.mineap.nInterpreter.operation.getMarker { 2 | import org.mineap.nInterpreter.IAnalyzeResult; 3 | import org.mineap.nInterpreter.ScriptLine; 4 | import org.mineap.nInterpreter.operation.IOperationAnalyzer; 5 | 6 | public class GetMarkerOperationAnalyzer implements IOperationAnalyzer { 7 | 8 | public static const GET_MARKER_OPERATION_PATTERN_1: RegExp = new RegExp("getMarker\\(name:['\"]([\\S]*)['\"]\\)"); 9 | 10 | public function GetMarkerOperationAnalyzer() { 11 | } 12 | 13 | public function analyze(source: ScriptLine): IAnalyzeResult { 14 | 15 | //getMarker(name:名前) 16 | 17 | var result: GetMarkerResult = null; 18 | var resultArray: Array = null; 19 | var line: String = source.line; 20 | 21 | resultArray = GET_MARKER_OPERATION_PATTERN_1.exec(line); 22 | if (resultArray != null && resultArray.length > 0) { 23 | result = new GetMarkerResult(); 24 | result.name = String(resultArray[1]); 25 | } 26 | 27 | return result; 28 | } 29 | } 30 | } -------------------------------------------------------------------------------- /src/org/mineap/nInterpreter/operation/getMarker/GetMarkerResult.as: -------------------------------------------------------------------------------- 1 | package org.mineap.nInterpreter.operation.getMarker { 2 | import org.mineap.nInterpreter.IAnalyzeResult; 3 | import org.mineap.nInterpreter.ResultType; 4 | 5 | /** 6 | * 7 | * @author shiraminekeisuke(MineAP) 8 | * 9 | */ 10 | public class GetMarkerResult implements IAnalyzeResult { 11 | 12 | /** 13 | * マーカの名前 14 | */ 15 | public var name: String; 16 | 17 | public function GetMarkerResult() { 18 | } 19 | 20 | public function get resultType(): ResultType { 21 | return ResultType.GET_MARKER; 22 | } 23 | 24 | } 25 | } -------------------------------------------------------------------------------- /src/org/mineap/nInterpreter/operation/jump/JumpResult.as: -------------------------------------------------------------------------------- 1 | package org.mineap.nInterpreter.operation.jump { 2 | import org.mineap.nInterpreter.IAnalyzeResult; 3 | import org.mineap.nInterpreter.ResultType; 4 | 5 | /** 6 | * jump命令の解析結果を格納するクラスです。 7 | * 8 | * @author shiraminekeisuke 9 | * 10 | */ 11 | public class JumpResult implements IAnalyzeResult { 12 | 13 | /** 14 | * 動画のIDを指定する。ちなみに id: は省略できる。 15 | */ 16 | public var id: String = ""; 17 | 18 | /** 19 | * ジャンプする直前にメッセージを表示する。未設定でもそれ用のメッセージが表示される。 20 | */ 21 | public var msg: String = ""; 22 | 23 | /** 24 | * 指定した再生時から再生する。ただし、移動先は動画を完全に読み込むまで再生が開始されなくなる。 25 | */ 26 | public var from: String = ""; 27 | 28 | /** 29 | * ジャンプした先の動画の再生を指定時間で終了する。 30 | */ 31 | public var length: String = ""; 32 | 33 | /** 34 | * trueなら再生終了時に移動前の動画へ戻る。 35 | */ 36 | public var isReturn: Boolean = false; 37 | 38 | /** 39 | * ジャンプ先から戻るときに表示される。 40 | */ 41 | public var returnMessage: String = ""; 42 | 43 | /** 44 | * trueなら新しいウインドウで、falseなら同じウィンドウでURLを開く。 45 | */ 46 | public var isNewWindow: Boolean = false; 47 | 48 | 49 | /** 50 | * このコンストラクタは何もしません。 51 | * 52 | */ 53 | public function JumpResult() { 54 | //jump(id:動画ID,msg:ジャンプメッセージ,from:開始位置,length:再生時間,return:戻り,returnmsg:戻りメッセージ,newwindow:対象窓) 55 | } 56 | 57 | 58 | /** 59 | * このResultクラスのタイプを返します。 60 | * 61 | * @return 62 | * 63 | */ 64 | public function get resultType(): ResultType { 65 | return ResultType.JUMP; 66 | } 67 | 68 | } 69 | } -------------------------------------------------------------------------------- /src/org/mineap/nInterpreter/operation/seek/SeekOperationAnalyzer.as: -------------------------------------------------------------------------------- 1 | package org.mineap.nInterpreter.operation.seek { 2 | import org.mineap.nInterpreter.IAnalyzeResult; 3 | import org.mineap.nInterpreter.ScriptLine; 4 | import org.mineap.nInterpreter.operation.IOperationAnalyzer; 5 | 6 | /** 7 | * 8 | * @author shiraminekeisuke 9 | * 10 | */ 11 | public class SeekOperationAnalyzer implements IOperationAnalyzer { 12 | 13 | /** 14 | * seek(vpos:時間) 15 | */ 16 | public static const SEEK_OPERATION_PATTERN_1: RegExp = new RegExp("seek\\(vpos:'?(\\d+)'?\\)"); 17 | 18 | /** 19 | * seek(vpos:時間,msg:文字列) 20 | */ 21 | public static const SEEK_OPERATION_PATTERN_2: RegExp = new RegExp("seek\\(vpos:'?(\\d+)'?,msg:([^\"]+)\\)"); 22 | 23 | /** 24 | * 25 | * 26 | */ 27 | public function SeekOperationAnalyzer() { 28 | } 29 | 30 | /** 31 | * seek命令を解析し、その結果を返します。 32 | * 33 | * @param source 解析したいseek命令 34 | * @return SeekResultオブジェクト 35 | * 36 | */ 37 | public function analyze(source: ScriptLine): IAnalyzeResult { 38 | //seek(vpos:時間,msg:文字列) 39 | 40 | var result: SeekResult = null; 41 | var resultArray: Array = null; 42 | var line: String = source.line; 43 | var paraCount: int = getParameterCount(line); 44 | 45 | if (paraCount >= 1) { 46 | 47 | switch (paraCount) { 48 | case 1: 49 | //引数が一つ 50 | resultArray = SEEK_OPERATION_PATTERN_1.exec(line); 51 | if (resultArray != null && resultArray.length > 0) { 52 | result = new SeekResult(); 53 | result.vpos = String(resultArray[1]); 54 | } 55 | break; 56 | case 2: 57 | resultArray = SEEK_OPERATION_PATTERN_2.exec(line); 58 | if (resultArray != null && resultArray.length > 0) { 59 | result = new SeekResult(); 60 | result.vpos = String(resultArray[1]); 61 | result.msg = String(resultArray[2]); 62 | } 63 | break; 64 | default: 65 | break; 66 | } 67 | } 68 | 69 | return result; 70 | } 71 | 72 | /** 73 | * パラメータの個数を返します。 74 | * @param source 75 | * @return 76 | * 77 | */ 78 | private function getParameterCount(source: String): int { 79 | 80 | var parameterSeparatorPattern: RegExp = new RegExp("(['\"][\\s]*,)+", "ig"); 81 | var array: Array = parameterSeparatorPattern.exec(source); 82 | var count: int = 1; 83 | while (array != null) { 84 | if (array.length > 0) { 85 | count++; 86 | } 87 | array = null; 88 | array = parameterSeparatorPattern.exec(source); 89 | } 90 | 91 | return count; 92 | } 93 | 94 | } 95 | } -------------------------------------------------------------------------------- /src/org/mineap/nInterpreter/operation/seek/SeekResult.as: -------------------------------------------------------------------------------- 1 | package org.mineap.nInterpreter.operation.seek { 2 | import org.mineap.nInterpreter.IAnalyzeResult; 3 | import org.mineap.nInterpreter.ResultType; 4 | 5 | /** 6 | * 7 | * @author shiraminekeisuke 8 | * 9 | */ 10 | public class SeekResult implements IAnalyzeResult { 11 | 12 | /** 13 | * 動画の再生位置を時間まで移動させる。再生時間のミリ秒を指定する。 14 | */ 15 | public var vpos: String = ""; 16 | 17 | /** 18 | * 文字列を設定した場合は移動する瞬間に画面が白で塗りつぶされ文字列が中央に表示される。 19 | */ 20 | public var msg: String = ""; 21 | 22 | /** 23 | * このコンストラクタは何もしません。 24 | * 25 | */ 26 | public function SeekResult() { 27 | //seek(vpos:時間,msg:文字列) 28 | } 29 | 30 | /** 31 | * このIAnalyzeResultオブジェクトのResultTypeを返します。 32 | * @return 33 | * 34 | */ 35 | public function get resultType(): ResultType { 36 | return ResultType.SEEK; 37 | } 38 | } 39 | } -------------------------------------------------------------------------------- /src/org/mineap/nicovideo4as: -------------------------------------------------------------------------------- 1 | ../../../nicovideo4as/src/org/mineap/nicovideo4as -------------------------------------------------------------------------------- /src/org/mineap/nndd/NNDDMyListsLoader.as: -------------------------------------------------------------------------------- 1 | package org.mineap.nndd { 2 | import flash.events.Event; 3 | import flash.net.URLLoader; 4 | import flash.net.URLRequest; 5 | 6 | import org.mineap.nndd.model.RssType; 7 | import org.mineap.nndd.myList.MyList; 8 | import org.mineap.nndd.server.RequestType; 9 | import org.mineap.util.config.ConfigManager; 10 | 11 | /** 12 | * NNDDServerからマイリストの一覧を取得するためのクラスです 13 | * 14 | * @author shiraminekeisuke 15 | * 16 | */ 17 | public class NNDDMyListsLoader extends URLLoader { 18 | private var _myLists: Vector. = new Vector.(); 19 | public static const GET_MYLISTS_COMPLETE: String = "GetMylistsComplete"; 20 | 21 | /** 22 | * 23 | * @param request 24 | * 25 | */ 26 | public function NNDDMyListsLoader(request: URLRequest = null) { 27 | addEventListener(Event.COMPLETE, completeEventHander); 28 | super(request); 29 | } 30 | 31 | 32 | /** 33 | * 34 | * @param nnddServerIpAddress 35 | * @param nnddServerPort 36 | * 37 | */ 38 | public function getMyLists(nnddServerAddress: String, nnddServerPort: int): void { 39 | var timeout: int = 1000; 40 | 41 | var timeoutStr: String = ConfigManager.getInstance().getItem("connectToNnddServerTimeout"); 42 | if (timeoutStr != null) { 43 | timeout = int(timeoutStr); 44 | } 45 | 46 | var reqXml: XML = ; 47 | reqXml.@type = RequestType.GET_MYLIST_LIST.typeStr; 48 | 49 | var urlRequest: URLRequest = new URLRequest("http://" + nnddServerAddress + ":" + nnddServerPort + 50 | "/NNDDServer"); 51 | urlRequest.method = "POST"; 52 | urlRequest.data = reqXml.toXMLString(); 53 | urlRequest.idleTimeout = timeout; 54 | 55 | super.load(urlRequest); 56 | 57 | } 58 | 59 | /** 60 | * 61 | * @param event 62 | * 63 | */ 64 | protected function completeEventHander(event: Event): void { 65 | 66 | var object: Object = (event.currentTarget as URLLoader).data; 67 | 68 | if (object != null) { 69 | var xml: XML = new XML(object); 70 | 71 | for each(var rss: XML in xml.rss) { 72 | var myListId: String = rss.@id; 73 | var myListType: String = rss.@rssType; 74 | var myListName: String = rss.@name; 75 | 76 | var myListUrl: String = myListId; 77 | 78 | var type: RssType = RssType.convertStrToRssType(myListType); 79 | switch (type) { 80 | case RssType.CHANNEL: 81 | myListUrl = "channel/" + myListId; 82 | break; 83 | case RssType.COMMUNITY: 84 | myListUrl = "community/" + myListId; 85 | break; 86 | case RssType.USER_UPLOAD_VIDEO: 87 | myListUrl = "user/" + myListId; 88 | break; 89 | default: 90 | myListUrl = "myList/" + myListId; 91 | } 92 | 93 | if (myListName == null || myListName.length == 0) { 94 | myListName = myListUrl; 95 | } 96 | 97 | var myList: MyList = new MyList(myListUrl, myListName); 98 | myList.type = type; 99 | 100 | _myLists.push(myList); 101 | 102 | trace("myListId:" + myListId + ", myListType:" + myListType + "," + myList.idWithPrefix); 103 | } 104 | } 105 | 106 | dispatchEvent(new Event(GET_MYLISTS_COMPLETE)); 107 | 108 | } 109 | 110 | /** 111 | * 112 | * @return 113 | * 114 | */ 115 | public function get myLists(): Vector. { 116 | return this._myLists; 117 | } 118 | 119 | 120 | } 121 | } -------------------------------------------------------------------------------- /src/org/mineap/nndd/SystemTrayIconManager.as: -------------------------------------------------------------------------------- 1 | package org.mineap.nndd { 2 | import flash.desktop.DockIcon; 3 | import flash.desktop.NativeApplication; 4 | import flash.desktop.SystemTrayIcon; 5 | import flash.display.Bitmap; 6 | import flash.display.BitmapData; 7 | import flash.display.Loader; 8 | import flash.display.LoaderInfo; 9 | import flash.display.NativeMenu; 10 | import flash.display.NativeMenuItem; 11 | import flash.events.Event; 12 | import flash.events.IOErrorEvent; 13 | import flash.net.URLRequest; 14 | 15 | import mx.core.Application; 16 | 17 | public class SystemTrayIconManager { 18 | 19 | public function setTrayIcon(): Boolean { 20 | 21 | var isSuccess: Boolean = false; 22 | 23 | // メニューの設定 24 | // var playMenuItem:NativeMenuItem = new NativeMenuItem("再生"); 25 | // playMenuItem.addEventListener(Event.SELECT, onPlay); 26 | var mainWindowMenuItem: NativeMenuItem = new NativeMenuItem("メインウィンドウ"); 27 | mainWindowMenuItem.addEventListener(Event.SELECT, onMainWindowOpen); 28 | var playerWindowMenuItem: NativeMenuItem = new NativeMenuItem("プレーヤー"); 29 | playerWindowMenuItem.addEventListener(Event.SELECT, onPlayerWindowOpen); 30 | 31 | var nativeMenu: NativeMenu = new NativeMenu(); 32 | // nativeMenu.addItem(playMenuItem); 33 | nativeMenu.addItem(mainWindowMenuItem); 34 | nativeMenu.addItem(playerWindowMenuItem); 35 | 36 | // Icon設定 37 | var loader: Loader = new Loader(); 38 | loader.contentLoaderInfo.addEventListener(Event.COMPLETE, iconLoadSuccessHandler); 39 | loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, iconLoadFailHandler); 40 | loader.contentLoaderInfo.addEventListener(IOErrorEvent.NETWORK_ERROR, iconLoadFailHandler); 41 | loader.contentLoaderInfo.addEventListener(IOErrorEvent.DISK_ERROR, iconLoadFailHandler); 42 | 43 | if (NativeApplication.supportsSystemTrayIcon) { 44 | 45 | loader.load(new URLRequest("icon32.png")); //Windows用は小さい方がきれいに見える? 46 | 47 | var separator: NativeMenuItem = new NativeMenuItem("", true); 48 | nativeMenu.addItem(separator); 49 | 50 | var exitMenuItem: NativeMenuItem = new NativeMenuItem("終了"); 51 | exitMenuItem.addEventListener(Event.SELECT, onExitMenuItem); 52 | nativeMenu.addItem(exitMenuItem); 53 | 54 | var systemTrayIcon: SystemTrayIcon = NativeApplication.nativeApplication.icon as SystemTrayIcon; 55 | systemTrayIcon.menu = nativeMenu; 56 | systemTrayIcon.tooltip = "NNDD"; 57 | 58 | trace("SystemTrayIcon Supported"); 59 | isSuccess = true; 60 | 61 | } else if (NativeApplication.supportsDockIcon) { 62 | 63 | loader.load(new URLRequest("icon128.png")); //Mac用はでかいのを使えば良いよ 64 | 65 | var dockIcon: DockIcon = NativeApplication.nativeApplication.icon as DockIcon; 66 | dockIcon.menu = nativeMenu; 67 | 68 | trace("DockIcon Supported"); 69 | isSuccess = true; 70 | } 71 | 72 | trace("トレイアイコン設定:" + isSuccess); 73 | 74 | return isSuccess; 75 | } 76 | 77 | private function onPlay(event: Event): void { 78 | Application.application.play(); 79 | } 80 | 81 | private function onMainWindowOpen(event: Event): void { 82 | Application.application.visible = true; 83 | Application.application.activate(); 84 | } 85 | 86 | private function onPlayerWindowOpen(event: Event): void { 87 | Application.application.playerOpen(); 88 | } 89 | 90 | private function iconLoadSuccessHandler(event: Event): void { 91 | var loader: LoaderInfo = LoaderInfo(event.currentTarget); 92 | var image: Bitmap = Bitmap(loader.content); 93 | var bitmapData: BitmapData = image.bitmapData; 94 | 95 | trace(event); 96 | 97 | NativeApplication.nativeApplication.icon.bitmaps = [bitmapData]; 98 | } 99 | 100 | private function iconLoadFailHandler(event: Event): void { 101 | trace(event); 102 | } 103 | 104 | private function onExitMenuItem(event: Event): void { 105 | Application.application.exitButtonClicked(); 106 | } 107 | 108 | 109 | } 110 | } -------------------------------------------------------------------------------- /src/org/mineap/nndd/download/DownloadStatusType.as: -------------------------------------------------------------------------------- 1 | package org.mineap.nndd.download { 2 | public class DownloadStatusType { 3 | 4 | /** 5 | * ダウンロードが完了しています(0) 6 | */ 7 | public static const COMPLETE: DownloadStatusType = new DownloadStatusType(0); 8 | 9 | /** 10 | * リトライオーバーでダウンロードを中止しました(1) 11 | */ 12 | public static const RETRY_OVER: DownloadStatusType = new DownloadStatusType(1); 13 | 14 | /** 15 | * ダウンロード中です(2) 16 | */ 17 | public static const DOWNLOADEING: DownloadStatusType = new DownloadStatusType(2); 18 | 19 | /** 20 | * ダウンロードが開始されていません(3) 21 | */ 22 | public static const NOT_START: DownloadStatusType = new DownloadStatusType(3); 23 | 24 | /** 25 | * エコノミーモードなのでスキップしました(4) 26 | */ 27 | public static const ECONOMY_SKIP: DownloadStatusType = new DownloadStatusType(4); 28 | 29 | private var _value: int = 0; 30 | 31 | public function DownloadStatusType(value: int) { 32 | this._value = value; 33 | } 34 | 35 | public function get value(): int { 36 | return this._value; 37 | } 38 | 39 | } 40 | } -------------------------------------------------------------------------------- /src/org/mineap/nndd/event/LibraryLoadEvent.as: -------------------------------------------------------------------------------- 1 | package org.mineap.nndd.event { 2 | import flash.events.Event; 3 | import flash.filesystem.File; 4 | 5 | public class LibraryLoadEvent extends Event { 6 | 7 | public static const LIBRARY_LOAD_COMPLETE: String = "LibraryLoadComplete"; 8 | public static const LIBRARY_LOADING: String = "LibraryLoading"; 9 | 10 | private var _loadingItem: File = null; 11 | 12 | private var _totalVideoCount: int = 0; 13 | 14 | private var _completeVideoCount: int = 0; 15 | 16 | /** 17 | * 18 | * @param type 19 | * @param bubbles 20 | * @param cancelable 21 | * @param totalVideoCount 22 | * @param completeVideoCount 23 | * @param loadingItem 24 | * 25 | */ 26 | public function LibraryLoadEvent( 27 | type: String, 28 | bubbles: Boolean = false, 29 | cancelable: Boolean = false, 30 | totalVideoCount: int = 0, 31 | completeVideoCount: int = 0, 32 | loadingItem: File = null 33 | ) { 34 | super(type, bubbles, cancelable); 35 | 36 | this._completeVideoCount = completeVideoCount; 37 | this._totalVideoCount = totalVideoCount; 38 | this._loadingItem = loadingItem; 39 | } 40 | 41 | /** 42 | * 43 | * @return 44 | * 45 | */ 46 | public function get totalVideoCount(): int { 47 | return _totalVideoCount; 48 | } 49 | 50 | /** 51 | * 52 | * @return 53 | * 54 | */ 55 | public function get completeVideoCount(): int { 56 | return _completeVideoCount; 57 | } 58 | 59 | /** 60 | * 61 | * @return 62 | * 63 | */ 64 | public function get loadingItem(): File { 65 | return _loadingItem; 66 | } 67 | 68 | 69 | } 70 | } -------------------------------------------------------------------------------- /src/org/mineap/nndd/event/LocalCommentSearchEvent.as: -------------------------------------------------------------------------------- 1 | package org.mineap.nndd.event { 2 | import flash.events.Event; 3 | import flash.filesystem.File; 4 | 5 | public class LocalCommentSearchEvent extends Event { 6 | 7 | /** 8 | * 9 | */ 10 | public static const LOCAL_COMMENT_SEARCH_COMPLETE: String = "LocalCommentSearchComplete"; 11 | 12 | private var _commentFiles: Vector. = new Vector.(); 13 | 14 | /** 15 | * 16 | * @param type 17 | * @param bubbles 18 | * @param cancelable 19 | * @param commentFiles 20 | * 21 | */ 22 | public function LocalCommentSearchEvent( 23 | type: String, 24 | bubbles: Boolean = false, 25 | cancelable: Boolean = false, 26 | commentFiles: Vector. = null 27 | ) { 28 | super(type, bubbles, cancelable); 29 | 30 | if (commentFiles != null) { 31 | this._commentFiles = commentFiles; 32 | } 33 | } 34 | 35 | /** 36 | * 37 | * @return 38 | * 39 | */ 40 | public function get commentFiles(): Vector. { 41 | return this._commentFiles; 42 | } 43 | } 44 | } -------------------------------------------------------------------------------- /src/org/mineap/nndd/event/MyListRenewProgressEvent.as: -------------------------------------------------------------------------------- 1 | package org.mineap.nndd.event { 2 | import flash.events.ProgressEvent; 3 | 4 | public class MyListRenewProgressEvent extends ProgressEvent { 5 | public static const MYLIST_RENEW_PROGRESS: String = "MyListRenewProgress"; 6 | 7 | private var _renewingMyListId: String = null; 8 | 9 | public function MyListRenewProgressEvent( 10 | type: String, 11 | bubbles: Boolean = false, 12 | cancelable: Boolean = false, 13 | bytesLoaded: Number = 0, 14 | bytesTotal: Number = 0, 15 | renewingMyListId: String = null 16 | ) { 17 | super(type, bubbles, cancelable, bytesLoaded, bytesTotal); 18 | this._renewingMyListId = renewingMyListId; 19 | } 20 | 21 | public function get renewingMyListId(): String { 22 | return this._renewingMyListId; 23 | } 24 | 25 | } 26 | } -------------------------------------------------------------------------------- /src/org/mineap/nndd/library/LibraryDirSearchUtil.as: -------------------------------------------------------------------------------- 1 | package org.mineap.nndd.library { 2 | import flash.filesystem.File; 3 | 4 | import org.mineap.nndd.LogManager; 5 | import org.mineap.nndd.model.VideoType; 6 | 7 | public class LibraryDirSearchUtil { 8 | private var _logger: LogManager; 9 | 10 | public function LibraryDirSearchUtil() { 11 | this._logger = LogManager.instance; 12 | } 13 | 14 | /** 15 | * 指定されたディレクトリを更新します。 16 | * 17 | * @param dir 更新対象ディレクトリ 18 | * @param renewSubDir サブディレクトリを更新するかどうか 19 | * 20 | */ 21 | public function renewDir(dir: File, renewSubDir: Boolean): Array { 22 | 23 | if (!dir.isDirectory) { 24 | // ディレクトリじゃなければ見に行かない 25 | return new Array(); 26 | } 27 | 28 | if (dir.nativePath == LibraryManagerBuilder.instance.libraryManager.systemFileDir.nativePath) { 29 | // systemディレクトリ下は見に行かない 30 | return new Array(); 31 | } 32 | 33 | var fileList: Array = dir.getDirectoryListing(); 34 | 35 | var videoList: Array = new Array(); 36 | 37 | for (var index: uint = 0; index < fileList.length; index++) { 38 | try { 39 | if (renewSubDir && fileList[index].isDirectory) { // サブディレクトリを探索 40 | var array: Array = renewDir((fileList[index] as File), true); 41 | 42 | for each(var obj: Object in array) { 43 | videoList.push(obj); 44 | } 45 | 46 | } else if (!fileList[index].isDirectory) { // このファイルが動画かどうかチェック 47 | 48 | var extension: String = (fileList[index] as File).extension; 49 | if (extension != null) { // 拡張子が無い場合はスキップ 50 | extension = extension.toUpperCase(); 51 | if (extension == VideoType.FLV_L || extension == VideoType.MP4_L) { 52 | 53 | videoList.push(fileList[index].url); 54 | 55 | } else if (extension == VideoType.SWF_L) { 56 | if ((fileList[index] as File).nativePath.indexOf(VideoType.NICOWARI) == -1) { 57 | videoList.push(fileList[index].url); 58 | } 59 | } 60 | } 61 | } 62 | } catch (error: Error) { 63 | _logger.addLog("次のフォルダ・ディレクトリを更新できませんでした:" + (fileList[index] as File).nativePath + ":" + error); 64 | trace(error.getStackTrace()); 65 | } 66 | } 67 | 68 | return videoList; 69 | } 70 | 71 | } 72 | } -------------------------------------------------------------------------------- /src/org/mineap/nndd/library/LibraryManagerBuilder.as: -------------------------------------------------------------------------------- 1 | package org.mineap.nndd.library { 2 | import org.mineap.nndd.library.namedarray.NamedArrayLibraryManager; 3 | import org.mineap.nndd.library.sqlite.SQLiteLibraryManager; 4 | 5 | /** 6 | * 7 | * @author shiraminekeisuke 8 | * 9 | */ 10 | public class LibraryManagerBuilder { 11 | private static const libraryManagerBuilder: LibraryManagerBuilder = new LibraryManagerBuilder(); 12 | 13 | /** 14 | * 15 | */ 16 | public static const LIBRARY_TYPE_SQL: String = "LibraryTypeSql"; 17 | 18 | /** 19 | * 20 | */ 21 | public static const LIBRARY_TYPE_NAMED_ARRAY: String = "LibraryTypeNamedArray"; 22 | 23 | private var _type: String = LibraryManagerBuilder.LIBRARY_TYPE_NAMED_ARRAY; 24 | 25 | /** 26 | * 27 | * @return 28 | * 29 | */ 30 | public static function get instance(): LibraryManagerBuilder { 31 | return libraryManagerBuilder; 32 | } 33 | 34 | /** 35 | * 36 | * 37 | */ 38 | public function LibraryManagerBuilder() { 39 | if (libraryManagerBuilder != null) { 40 | throw new ArgumentError("LibraryManagerBuilderはインスタンス化できません。"); 41 | } 42 | } 43 | 44 | /** 45 | * 46 | * @param type 47 | * 48 | */ 49 | public function set libraryType(type: String): void { 50 | 51 | if (LIBRARY_TYPE_SQL == type) { 52 | this._type = LIBRARY_TYPE_SQL; 53 | } else { 54 | this._type = LIBRARY_TYPE_NAMED_ARRAY; 55 | } 56 | 57 | } 58 | 59 | /** 60 | * 61 | * @return 62 | * 63 | */ 64 | public function get libraryManager(): ILibraryManager { 65 | 66 | if (LIBRARY_TYPE_NAMED_ARRAY == this._type) { 67 | return NamedArrayLibraryManager.instance; 68 | } else { 69 | return SQLiteLibraryManager.instance; 70 | } 71 | 72 | } 73 | 74 | } 75 | } -------------------------------------------------------------------------------- /src/org/mineap/nndd/library/sqlite/dao/VersionDao.as: -------------------------------------------------------------------------------- 1 | package org.mineap.nndd.library.sqlite.dao { 2 | import flash.data.SQLResult; 3 | import flash.data.SQLStatement; 4 | import flash.errors.SQLError; 5 | 6 | import org.mineap.nndd.library.sqlite.DbAccessHelper; 7 | import org.mineap.nndd.library.sqlite.Queries; 8 | 9 | /** 10 | * 11 | * @author shiraminekeisuke 12 | * 13 | */ 14 | public class VersionDao { 15 | 16 | private static const dao: VersionDao = new VersionDao(); 17 | 18 | private var _stmt: SQLStatement; 19 | 20 | /** 21 | * 22 | * @return 23 | * 24 | */ 25 | public static function get instance(): VersionDao { 26 | return dao; 27 | } 28 | 29 | /** 30 | * 31 | * 32 | */ 33 | public function VersionDao() { 34 | if (dao != null) { 35 | throw new ArgumentError("VersionDaoはインスタンス化できません。"); 36 | } 37 | } 38 | 39 | /** 40 | * 41 | * @param version 42 | * 43 | */ 44 | public function insertVersion(version: String): Boolean { 45 | try { 46 | 47 | this._stmt = new SQLStatement(); 48 | this._stmt.sqlConnection = DbAccessHelper.instance.connection; 49 | this._stmt.text = Queries.INSERT_VERSION; 50 | 51 | this._stmt.parameters[":id"] = 0; 52 | this._stmt.parameters[":version"] = version; 53 | 54 | this._stmt.execute(); 55 | 56 | return true; 57 | 58 | } catch (error: SQLError) { 59 | trace(error.getStackTrace()); 60 | } 61 | 62 | return false; 63 | } 64 | 65 | /** 66 | * 67 | * @param version 68 | * @return 69 | * 70 | */ 71 | public function updateVersion(version: String): Boolean { 72 | try { 73 | 74 | this._stmt = new SQLStatement(); 75 | this._stmt.sqlConnection = DbAccessHelper.instance.connection; 76 | this._stmt.text = Queries.UPDATE_VERSION; 77 | 78 | this._stmt.parameters[":id"] = 0; 79 | this._stmt.parameters[":version"] = version; 80 | 81 | this._stmt.execute(); 82 | 83 | return true; 84 | 85 | } catch (error: SQLError) { 86 | trace(error.getStackTrace()); 87 | } 88 | 89 | return false; 90 | } 91 | 92 | /** 93 | * 94 | * @return 95 | * 96 | */ 97 | public function selectVersion(): String { 98 | try { 99 | 100 | this._stmt = new SQLStatement(); 101 | this._stmt.sqlConnection = DbAccessHelper.instance.connection; 102 | this._stmt.text = Queries.SELECT_VERSION_BY_ID; 103 | 104 | this._stmt.parameters[":id"] = 0; 105 | 106 | this._stmt.execute(); 107 | 108 | var result: SQLResult = this._stmt.getResult(); 109 | if (result == null) { 110 | return null; 111 | } 112 | 113 | if (result.data == null) { 114 | return null; 115 | } 116 | 117 | if (result.data.length > 0) { 118 | 119 | var version: String = result.data[0].version; 120 | return version; 121 | 122 | } else { 123 | return null; 124 | } 125 | 126 | } catch (error: SQLError) { 127 | trace(error.getStackTrace()); 128 | } 129 | 130 | return null; 131 | } 132 | } 133 | } -------------------------------------------------------------------------------- /src/org/mineap/nndd/library/sqlite/util/DbMigrationUtil.as: -------------------------------------------------------------------------------- 1 | package org.mineap.nndd.library.sqlite.util { 2 | import flash.filesystem.File; 3 | 4 | import org.mineap.nndd.FileIO; 5 | import org.mineap.nndd.LogManager; 6 | import org.mineap.nndd.library.namedarray.LibraryXMLHelper; 7 | import org.mineap.nndd.library.sqlite.DbAccessHelper; 8 | import org.mineap.nndd.library.sqlite.dao.NNDDVideoDao; 9 | import org.mineap.nndd.model.NNDDVideo; 10 | 11 | /** 12 | * データベースのマイグレーションを担当するクラスです 13 | * 14 | * @author shiraminekeisuke(MineAP) 15 | * 16 | */ 17 | public class DbMigrationUtil { 18 | 19 | private var _logger: LogManager = LogManager.instance; 20 | 21 | /** 22 | * コンストラクタ 23 | * 24 | */ 25 | public function DbMigrationUtil() { 26 | } 27 | 28 | /** 29 | * 30 | * 31 | */ 32 | public function migrate(): void { 33 | 34 | _logger.addLog("DBの情報をXMLにして書き出し中..."); 35 | 36 | // テーブルの情報をXMLにして書き出し 37 | var file: File = export(); 38 | 39 | _logger.addLog("DBの定義を構築中..."); 40 | 41 | // テーブルをDropします 42 | DbAccessHelper.instance.dropTables(); 43 | 44 | // テーブルをCreateします 45 | DbAccessHelper.instance.createTables(); 46 | 47 | _logger.addLog("XMLの情報をDBに書き込み中..."); 48 | 49 | // テーブル情報をXMLからインポート 50 | importFromXML(file); 51 | 52 | _logger.addLog("完了."); 53 | 54 | } 55 | 56 | /** 57 | * NNDDVideoテーブルに関連するオブジェクトを全てフェッチして取り出した後、XMLにして保存します。 58 | * 59 | * @return 保存したXMLファイルを示すFileオブジェクト 60 | * 61 | */ 62 | private function export(): File { 63 | 64 | _logger.addLog("データベースの内容をXMLに変換"); 65 | 66 | var nnddVideos: Vector. = NNDDVideoDao.instance.selectAllNNDDVideo(); 67 | 68 | // Vectorを連想配列に変換 69 | var map: Object = new Object(); 70 | for each(var video: NNDDVideo in nnddVideos) { 71 | map[video.key] = video; 72 | } 73 | 74 | _logger.addLog("XMLへ変換(動画数:" + nnddVideos.length + ")"); 75 | 76 | // 連想配列からXMLに変換 77 | var xmlHelper: LibraryXMLHelper = new LibraryXMLHelper(); 78 | var libraryXML: XML = xmlHelper.convert(map); 79 | 80 | // XMLを保存 81 | var fileIO: FileIO = new FileIO(); 82 | var file: File = File.applicationStorageDirectory.resolvePath("library_back.xml"); 83 | // var file:File = SQLiteLibraryManager.instance.systemFileDir.resolvePath("library_back.xml"); 84 | 85 | _logger.addLog("変換したXMLを保存:" + file.nativePath); 86 | 87 | fileIO.saveXMLSync(file, libraryXML); 88 | 89 | return file; 90 | } 91 | 92 | /** 93 | * 94 | * @param file 95 | * 96 | */ 97 | private function importFromXML(file: File): void { 98 | 99 | _logger.addLog("ライブラリXMLを読み込み:" + file.nativePath); 100 | 101 | // XMLを読込み 102 | var fileIO: FileIO = new FileIO(); 103 | var libraryXML: XML = fileIO.loadXMLSync(file.url, true); 104 | 105 | _logger.addLog("ライブラリXMLを解析:" + file.nativePath); 106 | 107 | // XMLを連想配列に変換 108 | var xmlHelper: LibraryXMLHelper = new LibraryXMLHelper(); 109 | var map: Object = xmlHelper.perseXML(libraryXML); 110 | 111 | var nnddVideos: Vector. = new Vector.(); 112 | for each(var nnddVideo: NNDDVideo in map) { 113 | nnddVideos.push(nnddVideo); 114 | } 115 | 116 | NNDDVideoDao.instance.addNNDDVideos(nnddVideos, null, null); 117 | 118 | _logger.addLog("ライブラリXMLの解析結果をDBに保存(動画数:" + nnddVideos.length + ")"); 119 | 120 | } 121 | 122 | 123 | } 124 | } -------------------------------------------------------------------------------- /src/org/mineap/nndd/model/DownloadQueueItem.as: -------------------------------------------------------------------------------- 1 | package org.mineap.nndd.model { 2 | import org.mineap.nndd.util.PathMaker; 3 | 4 | public class DownloadQueueItem { 5 | 6 | /** 7 | * キューに追加したNNDDVideoです 8 | */ 9 | public var nnddVideo: NNDDVideo; 10 | 11 | /** 12 | * キューに追加した日付です 13 | */ 14 | public var date: Date; 15 | 16 | public function DownloadQueueItem(nnddVideo: NNDDVideo, date: Date = null) { 17 | this.nnddVideo = nnddVideo; 18 | if (date == null) { 19 | this.date = new Date(); 20 | } else { 21 | this.date = date; 22 | } 23 | } 24 | 25 | /** 26 | * ダウンロードIDを返します。 27 | * @return 28 | * 29 | */ 30 | public function getDownloadID(): String { 31 | return date.time.toString() + "-" + PathMaker.getVideoID(nnddVideo.getDecodeUrl()); 32 | } 33 | 34 | } 35 | } -------------------------------------------------------------------------------- /src/org/mineap/nndd/model/MyListRenewResultType.as: -------------------------------------------------------------------------------- 1 | package org.mineap.nndd.model { 2 | public final class MyListRenewResultType { 3 | 4 | public static const SUCCESS: MyListRenewResultType = new MyListRenewResultType("SUCCESS"); 5 | public static const FAIL: MyListRenewResultType = new MyListRenewResultType("FAIL"); 6 | 7 | private var _type: String; 8 | 9 | public function MyListRenewResultType(type: String) { 10 | this._type = type; 11 | } 12 | 13 | public function toString(): String { 14 | return this._type; 15 | } 16 | 17 | } 18 | } -------------------------------------------------------------------------------- /src/org/mineap/nndd/model/MyListSortType.as: -------------------------------------------------------------------------------- 1 | package org.mineap.nndd.model { 2 | public class MyListSortType { 3 | 4 | /** 5 | * 昇順か降順か 6 | */ 7 | public var sortFiledDescending: Boolean = false; 8 | 9 | /** 10 | * ソートを適用するフィールドの名前 11 | */ 12 | public var sortFiledName: String = null; 13 | 14 | 15 | /** 16 | * 17 | * @param name 18 | * @param descending 19 | * 20 | */ 21 | public function MyListSortType(name: String, descending: Boolean) { 22 | this.sortFiledName = name; 23 | this.sortFiledDescending = descending; 24 | } 25 | } 26 | } -------------------------------------------------------------------------------- /src/org/mineap/nndd/model/NNDDComment.as: -------------------------------------------------------------------------------- 1 | package org.mineap.nndd.model { 2 | import org.mineap.nicovideo4as.model.Comment; 3 | import org.mineap.nndd.player.comment.Command; 4 | 5 | public class NNDDComment extends Comment { 6 | 7 | private var _isShow: Boolean = true; 8 | 9 | private var _sizeCommand: int = Command.MEDIUM; 10 | 11 | /** 12 | * 13 | * @param vpos 14 | * @param text 15 | * @param mail 16 | * @param user_id 17 | * @param no 18 | * @param thread 19 | * @param date 20 | * @param isShow 21 | * 22 | */ 23 | public function NNDDComment( 24 | vpos: Number, 25 | text: String, 26 | mail: String, 27 | user_id: String, 28 | no: Number, 29 | thread: String, 30 | date: Number, 31 | isShow: Boolean 32 | ) { 33 | 34 | super(vpos, text, mail, user_id, no, thread, date); 35 | this._isShow = isShow; 36 | 37 | } 38 | 39 | public function get isShow(): Boolean { 40 | return _isShow; 41 | } 42 | 43 | public function set isShow(value: Boolean): void { 44 | _isShow = value; 45 | } 46 | 47 | public function get sizeCommand(): int { 48 | return _sizeCommand; 49 | } 50 | 51 | public function set sizeCommand(value: int): void { 52 | _sizeCommand = value; 53 | } 54 | 55 | 56 | } 57 | } -------------------------------------------------------------------------------- /src/org/mineap/nndd/model/NNDDFile.as: -------------------------------------------------------------------------------- 1 | package org.mineap.nndd.model { 2 | import flash.filesystem.File; 3 | 4 | public class NNDDFile extends File { 5 | 6 | private var _id: Number = -1; 7 | 8 | public function NNDDFile(path: String = null) { 9 | super(path); 10 | } 11 | 12 | public function get id(): Number { 13 | return _id; 14 | } 15 | 16 | public function set id(value: Number): void { 17 | _id = value; 18 | } 19 | 20 | } 21 | } -------------------------------------------------------------------------------- /src/org/mineap/nndd/model/NNDDSearchSortType.as: -------------------------------------------------------------------------------- 1 | package org.mineap.nndd.model { 2 | import org.mineap.nicovideo4as.model.search.SearchOrderType; 3 | import org.mineap.nicovideo4as.model.search.SearchSortType; 4 | 5 | /** 6 | * NNDDSearchSortType.as
7 | * NNDDSearchSortTypeクラスは、検索結果のソート順に関する定数を保持するクラスです。
8 | *
9 | * Copyright (c) 2009 MAP - MineApplicationProject. All Rights Reserved.
10 | * 11 | * @author shiraminekeisuke 12 | * 13 | */ 14 | public class NNDDSearchSortType { 15 | 16 | /** 17 | * 投稿日時 18 | */ 19 | public static const CONTRIBUTE: int = 0; 20 | /** 21 | * 再生数 22 | */ 23 | public static const PLAY_COUNT: int = 1; 24 | /** 25 | * コメント数 26 | */ 27 | public static const COMMENT_COUNT: int = 2; 28 | /** 29 | * コメント日時 30 | */ 31 | public static const COMMENT_TIME: int = 3; 32 | /** 33 | * マイリスト 34 | */ 35 | public static const MYLIST_COUNT: int = 4; 36 | /** 37 | * 再生時間 38 | */ 39 | public static const PLAY_TIME: int = 5; 40 | 41 | 42 | /** 43 | * 降順 (descending) 新しい、多い、長い 44 | */ 45 | public static const ORDER_D: int = 0; 46 | /** 47 | * 昇順 (ascending) 古い、少ない、短い 48 | */ 49 | public static const ORDER_A: int = 1; 50 | 51 | /** 52 | * 指定されたintのソート順序をnicovideo4asのSearchSortTypeに変換して返します 53 | * 54 | * @param type 55 | * @return 56 | * 57 | */ 58 | public static function convertSortTypeNumToN4A(type: int): SearchSortType { 59 | 60 | var typeStr: SearchSortType = SearchSortType.MYLIST_COUNTER; 61 | 62 | switch (type) { 63 | case COMMENT_TIME: 64 | typeStr = SearchSortType.NEW_COMMENT; 65 | break; 66 | case PLAY_COUNT: 67 | typeStr = SearchSortType.VIEW_COUNTER; 68 | break; 69 | case COMMENT_COUNT: 70 | typeStr = SearchSortType.NUM_RES; 71 | break; 72 | case MYLIST_COUNT: 73 | typeStr = SearchSortType.MYLIST_COUNTER; 74 | break; 75 | case CONTRIBUTE: 76 | typeStr = SearchSortType.FIRST_RETRIVE; 77 | break; 78 | case PLAY_TIME: 79 | typeStr = SearchSortType.LENGTH; 80 | break; 81 | } 82 | 83 | return typeStr; 84 | } 85 | 86 | /** 87 | * 指定されたオーダーのint表現に対応するnicovideo4asのSearchOrderTypeを返します 88 | * 89 | * @param order 90 | * @return 91 | * 92 | */ 93 | public static function convertSortOrderTypeNumToN4A(order: int): SearchOrderType { 94 | if (order == ORDER_A) { 95 | return SearchOrderType.ASCENDING; 96 | } 97 | return SearchOrderType.DESCENDING; 98 | } 99 | 100 | /** 101 | * 102 | */ 103 | public var sort: int = 0; 104 | 105 | /** 106 | * 107 | */ 108 | public var order: int = 0; 109 | 110 | /** 111 | * 112 | * @param sort 113 | * @param order 114 | * 115 | */ 116 | public function NNDDSearchSortType(sort: int, order: int) { 117 | this.sort = sort; 118 | this.order = order; 119 | } 120 | } 121 | } -------------------------------------------------------------------------------- /src/org/mineap/nndd/model/NNDDSearchType.as: -------------------------------------------------------------------------------- 1 | package org.mineap.nndd.model { 2 | /** 3 | * SearchType.as
4 | * SearchTypeクラスは、検索種別を表す定数を保持するクラスです。
5 | *
6 | * Copyright (c) 2009 MAP - MineApplicationProject. All Rights Reserved.
7 | * 8 | * @author shiraminekeisuke 9 | * 10 | */ 11 | public class NNDDSearchType { 12 | /** 13 | * 検索種別がキーワードである事を表す定数です 14 | */ 15 | public static const KEY_WORD: int = 0; 16 | /** 17 | * 検索種別がタグによる検索である事を表す定数です 18 | */ 19 | public static const TAG: int = 1; 20 | 21 | public function NNDDSearchType() { 22 | } 23 | } 24 | } -------------------------------------------------------------------------------- /src/org/mineap/nndd/model/NicoVideoRSS.as: -------------------------------------------------------------------------------- 1 | package org.mineap.nndd.model { 2 | import org.mineap.nndd.util.MyListUtil; 3 | 4 | /** 5 | * マイリストやチャネルなどの、RSSのアドレスを表現するクラスです。 6 | * 7 | * (v2.1では未使用) 8 | * 9 | * @author shiraminekeisuke (MineAP) 10 | * 11 | */ 12 | public class NicoVideoRSS { 13 | 14 | /** 15 | * RSSのURLです
16 | * ただし、URLとは限りません。URL以外にも、mylist/*****や、*****の形式である事があります。 17 | */ 18 | public var url: String = ""; 19 | 20 | /** 21 | * NNDD上で管理するためのRSSの名前です 22 | */ 23 | public var name: String = ""; 24 | 25 | /** 26 | * このマイリストオブジェクトがディレクトリを表すかどうかです。 27 | */ 28 | public var isDir: Boolean = false; 29 | 30 | /** 31 | * 未読動画数 32 | */ 33 | public var unPlayVideoCount: int = 0; 34 | 35 | /** 36 | * RSSに登録されている動画IDの一覧 37 | */ 38 | private var videoIds: Object = new Object(); 39 | 40 | /** 41 | * コンストラクタ。 42 | * 43 | * @param url 44 | * @param name 45 | * @param isDir 46 | * @param videoIds 47 | */ 48 | public function NicoVideoRSS( 49 | url: String, 50 | name: String, 51 | isDir: Boolean = false, 52 | videoIds: Vector. = null 53 | ) { 54 | if (url != null) { 55 | this.url = url; 56 | } 57 | if (name != null) { 58 | this.name = name; 59 | } 60 | 61 | this.isDir = isDir; 62 | 63 | if (videoIds != null) { 64 | for each(var id: String in videoIds) { 65 | videoIds[id] = id; 66 | } 67 | } 68 | } 69 | 70 | /** 71 | * このRSSのマイリストIDを返します 72 | * @return 73 | * 74 | */ 75 | public function get id(): String { 76 | return MyListUtil.getMyListId(this.url); 77 | } 78 | 79 | /** 80 | * このマイリストオブジェクトに、指定された動画IDを登録します 81 | * 82 | * @param video 83 | * 84 | */ 85 | public function addNNDDVideoId(videoId: String): void { 86 | if (videoId == null) { 87 | videoIds[videoId] = videoId; 88 | } 89 | } 90 | 91 | /** 92 | * このマイリストオブジェクトから、指定された動画IDを取り除きます 93 | * 94 | * @param videoId 95 | * 96 | */ 97 | public function deleteNNDDVideoId(videoId: String): void { 98 | if (videoId == null) { 99 | delete videoIds[videoId]; 100 | } 101 | } 102 | 103 | /** 104 | * このマイリストオブジェクトが保持する動画IDを全てクリアします 105 | * 106 | */ 107 | public function clearNNDDVideoId(): void { 108 | videoIds = new Object(); 109 | } 110 | 111 | /** 112 | * 指定された動画IDがこのマイリストに登録されているかどうか調べます 113 | * 114 | * @param videoId 115 | * @return 116 | * 117 | */ 118 | public function contains(videoId: String): Boolean { 119 | if (videoIds[videoId] != null) { 120 | return true; 121 | } 122 | return false; 123 | } 124 | 125 | } 126 | } -------------------------------------------------------------------------------- /src/org/mineap/nndd/model/PlayList.as: -------------------------------------------------------------------------------- 1 | package org.mineap.nndd.model { 2 | /** 3 | * 4 | * プレイリスト一つを管理します。 5 | * 6 | * @author shiraminekeisuke 7 | * 8 | */ 9 | public class PlayList { 10 | 11 | /** 12 | * プレイリスト名です 13 | */ 14 | public var name: String = ""; 15 | 16 | /** 17 | * プレイリストに登録されている項目です 18 | */ 19 | public var items: Vector. = new Vector.(); 20 | 21 | /** 22 | * プレイリストオブジェクトがフォルダかどうかを表します 23 | */ 24 | public var isDir: Boolean = false; 25 | 26 | 27 | /** 28 | * コンストラクタ
29 | * プレイリストを生成します。 30 | * 31 | * @param name プレイリストの名前を指定します 32 | * @param items プレイリストに格納する項目を指定します 33 | * @param isDir プレイリストがフォルダかどうかを表します 34 | * 35 | */ 36 | public function PlayList(name: String = "", items: Vector. = null, isDir: Boolean = false) { 37 | if (name != null && name != "") { 38 | this.name = name; 39 | } 40 | if (items != null) { 41 | this.items = items; 42 | } 43 | this.isDir = isDir; 44 | 45 | } 46 | } 47 | } -------------------------------------------------------------------------------- /src/org/mineap/nndd/model/RssType.as: -------------------------------------------------------------------------------- 1 | package org.mineap.nndd.model { 2 | public class RssType { 3 | 4 | public static const MY_LIST: RssType = new RssType("MY_LIST"); 5 | 6 | public static const CHANNEL: RssType = new RssType("CHANNEL"); 7 | 8 | public static const COMMUNITY: RssType = new RssType("COMMUNITY"); 9 | 10 | public static const USER_UPLOAD_VIDEO: RssType = new RssType("USER_UPLOAD_VIDEO"); 11 | 12 | private var value: String = null; 13 | 14 | public function RssType(value: String) { 15 | this.value = value; 16 | } 17 | 18 | public function toString(): String { 19 | return value; 20 | } 21 | 22 | public static function convertStrToRssType(typeStr: String): RssType { 23 | switch (typeStr) { 24 | case MY_LIST.value: 25 | return MY_LIST; 26 | case CHANNEL.value: 27 | return CHANNEL; 28 | case COMMUNITY.value: 29 | return COMMUNITY; 30 | case USER_UPLOAD_VIDEO.value: 31 | return USER_UPLOAD_VIDEO; 32 | default: 33 | return null; 34 | } 35 | } 36 | 37 | } 38 | } -------------------------------------------------------------------------------- /src/org/mineap/nndd/model/Schedule.as: -------------------------------------------------------------------------------- 1 | package org.mineap.nndd.model { 2 | import flash.events.EventDispatcher; 3 | 4 | /** 5 | * スケジュールを表すオブジェクトです。
6 | * 1.間隔(毎週、毎日)
7 | * 2.間隔が毎週の場合は、実行する曜日
8 | * 3.時間(時、分)
9 | * を保持します。
10 | *
11 | * Copyright (c) 2009 MAP - MineApplicationProject. All Rights Reserved. 12 | * 13 | * @author shiraminekeisuke 14 | * 15 | */ 16 | public class Schedule extends EventDispatcher { 17 | 18 | /** 19 | * 「毎週」を表す定数です 20 | */ 21 | public static const WEEKLY: int = 0; 22 | 23 | /** 24 | * 「毎日」を表す定数です 25 | */ 26 | public static const DAILY: int = 1; 27 | 28 | /** 29 | * 間隔を表す文字列表現です。 30 | */ 31 | public static const INTERVAL_NAME_ARRAY: Array = new Array("毎週", "毎日"); 32 | 33 | /** 34 | * 曜日を表す文字列表現です。 35 | */ 36 | public static const DAY_NAME_ARRAY: Array = new Array("日曜", "月曜", "火曜", "水曜", "木曜", "金曜", "土曜"); 37 | 38 | /** 39 | * スケジュール実行間隔です 40 | */ 41 | public var interval: int = Schedule.WEEKLY; 42 | 43 | /** 44 | * スケジュール実行間隔が「毎週」の時の実行する曜日です 45 | */ 46 | public var dayOfTheWeek: int = -1; 47 | 48 | /** 49 | * スケジュールを実行する時間です 50 | */ 51 | public var hour: int = 0; 52 | 53 | /** 54 | * スケジュールを実行する分です 55 | */ 56 | public var minutes: int = 0; 57 | 58 | /** 59 | * コンストラクタ。
60 | * @param interval スケジュール間隔。Schedule.DAILYかSchedule.WEEKLYを指定します。 61 | * @param dayOfTheWeek 曜日を指定します。「日、月、火、水、木、金、土」に対応する数字、「0,1,2,3,4,5,6」を指定してください。 62 | * @param hour 時間を指定します。0-23の値です。 63 | * @param minites 分を指定します。0-59の値です。 64 | * 65 | */ 66 | public function Schedule( 67 | interval: int = Schedule.DAILY, 68 | dayOfTheWeek: int = -1, 69 | hour: int = 0, 70 | minites: int = 0 71 | ) { 72 | this.interval = interval; 73 | 74 | if (interval == Schedule.WEEKLY) { 75 | this.dayOfTheWeek = dayOfTheWeek; 76 | } else { 77 | this.dayOfTheWeek = -1; 78 | } 79 | 80 | this.hour = hour; 81 | 82 | this.minutes = minites; 83 | } 84 | 85 | /** 86 | * 設定された曜日の文字列表現を返します。
87 | * ただし、曜日が-1の時は空の文字列を返します。 88 | * @return 89 | * 90 | */ 91 | public function get dayString(): String { 92 | if (this.dayOfTheWeek == -1) { 93 | return ""; 94 | } 95 | return Schedule.DAY_NAME_ARRAY[this.dayOfTheWeek]; 96 | } 97 | 98 | /** 99 | * 設定された間隔の文字列表現を返します。 100 | * @return 101 | * 102 | */ 103 | public function get intervalString(): String { 104 | return Schedule.INTERVAL_NAME_ARRAY[this.interval]; 105 | } 106 | 107 | /** 108 | * 設定された時間の文字列表現を返します。 109 | * @return 110 | * 111 | */ 112 | public function get timeString(): String { 113 | var hours: String = String(this.hour); 114 | var minutes: String = String(this.minutes); 115 | if (hours.length == 1) { 116 | hours = "0" + hours; 117 | } 118 | if (minutes.length == 1) { 119 | minutes = "0" + minutes; 120 | } 121 | 122 | return hours + ":" + minutes; 123 | } 124 | 125 | } 126 | } -------------------------------------------------------------------------------- /src/org/mineap/nndd/model/SearchItem.as: -------------------------------------------------------------------------------- 1 | package org.mineap.nndd.model { 2 | 3 | /** 4 | * SearchItem.as
5 | * SearchItemクラスは、検索条件を保持するクラスです。
6 | *
7 | * Copyright (c) 2009 MAP - MineApplicationProject. All Rights Reserved. 8 | * 9 | * @author shiraminekeisuke 10 | * 11 | */ 12 | public class SearchItem { 13 | 14 | /** 15 | * 検索条件名 16 | */ 17 | public var name: String = "検索条件"; 18 | 19 | /** 20 | * 検索結果のソート種別 21 | */ 22 | public var sortType: NNDDSearchSortType = new NNDDSearchSortType( 23 | NNDDSearchSortType.COMMENT_TIME, 24 | NNDDSearchSortType.ORDER_D 25 | ); 26 | 27 | /** 28 | * 検索の種別(キーワード、タグ) 29 | */ 30 | public var searchType: int = SearchTypeString.NICO_SEARCH_TYPE_TEXT[0]; 31 | 32 | /** 33 | * 検索対象文字列 34 | */ 35 | public var searchWord: String = ""; 36 | 37 | /** 38 | * この検索項目がディレクトリを表すかどうか 39 | */ 40 | public var isDir: Boolean = false; 41 | 42 | /** 43 | * コンストラクタ
44 | * @param name 45 | * @param sortType 46 | * @param searchType 47 | * @param searchWord 48 | * @param isDir 49 | * 50 | */ 51 | public function SearchItem( 52 | name: String, 53 | sortType: NNDDSearchSortType, 54 | searchType: int, 55 | searchWord: String, 56 | isDir: Boolean = false 57 | ) { 58 | this.name = name; 59 | this.sortType = sortType; 60 | this.searchType = searchType; 61 | this.searchWord = searchWord; 62 | this.isDir = isDir; 63 | } 64 | 65 | } 66 | } -------------------------------------------------------------------------------- /src/org/mineap/nndd/model/SearchSortString.as: -------------------------------------------------------------------------------- 1 | package org.mineap.nndd.model { 2 | 3 | /** 4 | * 検索ソート順の文字列を表現するクラスです。 5 | * 6 | * @author shiraminekeisuke(MineAP) 7 | * 8 | */ 9 | public class SearchSortString { 10 | 11 | /** 12 | * 検索結果のソート順の文字列表現です 13 | */ 14 | public static const NICO_SEARCH_SORT_TEXT_ARRAY: Array = new Array( 15 | "投稿が新しい順", 16 | "投稿が古い順", 17 | "再生が多い順", 18 | "再生が少ない順", 19 | "コメントが多い順", 20 | "コメントが少ない順", 21 | "コメントが新しい順", 22 | "コメントが古い順", 23 | "マイリストが多い順", 24 | "マイリストが少ない順", 25 | "再生時間が長い順", 26 | "再生時間が短い順" 27 | ); 28 | 29 | /** 30 | * 指定されたソート順文字列表現の配列インデックスから SearchSortType を返します。 31 | * 32 | * @param index 33 | * @return 34 | * 35 | */ 36 | public static function convertSortTypeFromIndex(index: int): NNDDSearchSortType { 37 | return convertSortTypeFromString(NICO_SEARCH_SORT_TEXT_ARRAY[index]); 38 | } 39 | 40 | /** 41 | * 指定されたソート順の文字列表現から SearchSortType を返します。 42 | * 43 | * @param text 44 | * @return 45 | * 46 | */ 47 | public static function convertSortTypeFromString(text: String): NNDDSearchSortType { 48 | 49 | for (var index: int = 0; NICO_SEARCH_SORT_TEXT_ARRAY.length > index; index++) { 50 | if (NICO_SEARCH_SORT_TEXT_ARRAY[index] == text) { 51 | var order: int = NNDDSearchSortType.ORDER_D; 52 | if ((index % 2) == 1) { 53 | // 2で割ったあまりが1 54 | order = NNDDSearchSortType.ORDER_A; 55 | } 56 | 57 | return new NNDDSearchSortType(index / 2, order); 58 | } 59 | } 60 | 61 | return new NNDDSearchSortType(NNDDSearchSortType.COMMENT_COUNT, NNDDSearchSortType.ORDER_D); 62 | } 63 | 64 | /** 65 | * SearchSortTypeから対応するNICO_SEARCH_SORT_TEXT_ARRAYのインデックスを返します 66 | * @param searchSortType 67 | * @return 68 | * 69 | */ 70 | public static function convertTextArrayIndexFromSearchSortType(searchSortType: NNDDSearchSortType): int { 71 | var index: int = 0; 72 | index = searchSortType.sort * 2; 73 | index += searchSortType.order; 74 | return index; 75 | } 76 | 77 | } 78 | } -------------------------------------------------------------------------------- /src/org/mineap/nndd/model/SearchTypeString.as: -------------------------------------------------------------------------------- 1 | package org.mineap.nndd.model { 2 | /** 3 | * 4 | * @author shiraminekeisuke 5 | * 6 | */ 7 | public class SearchTypeString { 8 | 9 | /** 10 | * 検索種別の文字列表現です 11 | */ 12 | public static const NICO_SEARCH_TYPE_TEXT: Array = new Array("キーワード", "タグ"//, "タグを" 13 | ); 14 | 15 | public function SearchTypeString() { 16 | } 17 | } 18 | } -------------------------------------------------------------------------------- /src/org/mineap/nndd/model/TagString.as: -------------------------------------------------------------------------------- 1 | package org.mineap.nndd.model { 2 | /** 3 | * 4 | * @author shiraminekeisuke 5 | * 6 | */ 7 | public class TagString { 8 | 9 | private var _id: Number = -1; 10 | 11 | private var _tag: String = null; 12 | 13 | /** 14 | * 15 | * @param tag 16 | * 17 | */ 18 | public function TagString(tag: String = null) { 19 | if (tag != null) { 20 | _tag = tag; 21 | } 22 | } 23 | 24 | public function get id(): Number { 25 | return _id; 26 | } 27 | 28 | public function set id(value: Number): void { 29 | _id = value; 30 | } 31 | 32 | public function get tag(): String { 33 | return _tag; 34 | } 35 | 36 | public function set tag(value: String): void { 37 | _tag = value; 38 | } 39 | 40 | 41 | } 42 | } -------------------------------------------------------------------------------- /src/org/mineap/nndd/model/VideoType.as: -------------------------------------------------------------------------------- 1 | package org.mineap.nndd.model { 2 | /** 3 | * 4 | * 動画の拡張子を保持するクラスです。
5 | * 6 | * @author shiraminekeisuke (MineAP) 7 | * 8 | */ 9 | public class VideoType { 10 | 11 | public static const SWF_S: String = "swf"; 12 | public static const SWF_L: String = "SWF"; 13 | public static const FLV_S: String = "flv"; 14 | public static const FLV_L: String = "FLV"; 15 | public static const MP4_S: String = "mp4"; 16 | public static const MP4_L: String = "MP4"; 17 | public static const HTML_S: String = "html"; 18 | public static const HTML_L: String = "HTML"; 19 | public static const XML_S: String = "xml"; 20 | public static const XML_L: String = "XML"; 21 | public static const JPEG_S: String = "jpeg"; 22 | public static const JPEG_L: String = "JPEG"; 23 | 24 | /** 25 | * ニコ割かどうか 26 | */ 27 | public static const NICOWARI: String = "[Nicowari]"; 28 | 29 | public function VideoType() { 30 | } 31 | } 32 | } -------------------------------------------------------------------------------- /src/org/mineap/nndd/model/tree/ITreeItem.as: -------------------------------------------------------------------------------- 1 | package org.mineap.nndd.model.tree { 2 | import flash.filesystem.File; 3 | 4 | /** 5 | * 6 | * @author shiraminekeisuke 7 | * 8 | */ 9 | public interface ITreeItem { 10 | 11 | function get label(): String; 12 | 13 | function set label(label: String): void; 14 | 15 | function get file(): File; 16 | 17 | function get parent(): ITreeItem; 18 | 19 | function set parent(value: ITreeItem): void; 20 | 21 | 22 | } 23 | } -------------------------------------------------------------------------------- /src/org/mineap/nndd/model/tree/TreeFileItem.as: -------------------------------------------------------------------------------- 1 | package org.mineap.nndd.model.tree { 2 | import flash.filesystem.File; 3 | 4 | /** 5 | * 6 | * @author shiraminekeisuke(MineAP) 7 | * 8 | */ 9 | public dynamic class TreeFileItem implements ITreeItem { 10 | private var _label: String; 11 | 12 | private var _file: File; 13 | 14 | private var _parent: ITreeItem; 15 | 16 | /** 17 | * 18 | * @param file 19 | * 20 | */ 21 | public function TreeFileItem(file: File = null) { 22 | this._file = file; 23 | } 24 | 25 | public function get label(): String { 26 | return this._label; 27 | } 28 | 29 | public function set label(value: String): void { 30 | this._label = value; 31 | } 32 | 33 | public function get file(): File { 34 | return _file; 35 | } 36 | 37 | public function get parent(): ITreeItem { 38 | return _parent; 39 | } 40 | 41 | public function set parent(value: ITreeItem): void { 42 | _parent = value; 43 | } 44 | 45 | 46 | } 47 | } -------------------------------------------------------------------------------- /src/org/mineap/nndd/model/tree/TreeFolderItem.as: -------------------------------------------------------------------------------- 1 | package org.mineap.nndd.model.tree { 2 | import flash.filesystem.File; 3 | 4 | /** 5 | * 6 | * @author shiraminekeisuke(MineAP) 7 | * 8 | */ 9 | public dynamic class TreeFolderItem implements ITreeItem { 10 | 11 | private var _label: String; 12 | 13 | private var _children: Array; 14 | 15 | private var _file: File; 16 | 17 | private var _parent: ITreeItem; 18 | 19 | /** 20 | * 21 | * @param file 22 | * 23 | */ 24 | public function TreeFolderItem(file: File = null) { 25 | _file = file; 26 | } 27 | 28 | public function get label(): String { 29 | return this._label; 30 | } 31 | 32 | public function set label(value: String): void { 33 | this._label = value; 34 | } 35 | 36 | public function get children(): Array { 37 | return this._children; 38 | } 39 | 40 | public function set children(value: Array): void { 41 | this._children = value; 42 | } 43 | 44 | public function get file(): File { 45 | return _file; 46 | } 47 | 48 | public function set file(value: File): void { 49 | this._file = value; 50 | } 51 | 52 | public function get parent(): ITreeItem { 53 | return _parent; 54 | } 55 | 56 | public function set parent(value: ITreeItem): void { 57 | _parent = value; 58 | } 59 | 60 | } 61 | } -------------------------------------------------------------------------------- /src/org/mineap/nndd/myList/MyListHistoryManager.as: -------------------------------------------------------------------------------- 1 | package org.mineap.nndd.myList { 2 | import org.mineap.util.config.ConfigManager; 3 | 4 | /** 5 | * マイリストの履歴を保持するクラス。 6 | * 7 | * @author shiraminekeisuke(MineAP) 8 | * 9 | */ 10 | public class MyListHistoryManager { 11 | 12 | private static const manager: MyListHistoryManager = new MyListHistoryManager(); 13 | 14 | private var maxHistoryCount: int = 10; 15 | 16 | private var history: Vector. = new Vector.(); 17 | 18 | /** 19 | * 20 | * 21 | */ 22 | public function MyListHistoryManager() { 23 | if (manager != null) { 24 | throw new ArgumentError("MyListHistoryManagerはインスタンス化できません。"); 25 | } 26 | 27 | for (var i: int = 0; i < 10; i++) { 28 | var name: String = ConfigManager.getInstance().getItem("myListHistoryName" + i); 29 | var url: String = ConfigManager.getInstance().getItem("myListHistoryUrl" + i); 30 | 31 | if (url != null && url.length > 0) { 32 | history.push(new MyList(url, name, false, null)); 33 | } else { 34 | break; 35 | } 36 | 37 | } 38 | } 39 | 40 | /** 41 | * シングルトンパターン 42 | * 43 | * @return 44 | * 45 | */ 46 | public static function get instace(): MyListHistoryManager { 47 | return manager; 48 | } 49 | 50 | /** 51 | * 52 | * @param myList 53 | * 54 | */ 55 | public function addHistory(myList: MyList): void { 56 | if (myList == null) { 57 | return; 58 | } 59 | if (myList.isDir) { 60 | return; 61 | } 62 | if (myList.id == null) { 63 | return; 64 | } 65 | 66 | // すでに登録済みでないかチェック 67 | var exist: Boolean = false; 68 | var index: int = 0; 69 | for each (var addedItem: MyList in history) { 70 | if (myList.idWithPrefix == addedItem.idWithPrefix) { 71 | exist = true; 72 | break; 73 | } 74 | index++; 75 | } 76 | 77 | // 重複した項目があったら削除 78 | if (exist) { 79 | history.splice(index, 1); 80 | } 81 | 82 | // 先頭に追加 83 | history.splice(0, 0, myList); 84 | 85 | 86 | // サイズを10以下にする 87 | while (true) { 88 | if (history.length > 10) { 89 | history.splice(-1, 1); 90 | } else { 91 | break; 92 | } 93 | } 94 | 95 | saveHistory(); 96 | 97 | } 98 | 99 | /** 100 | * 履歴を返します。 101 | * @return 102 | * 103 | */ 104 | public function getHistory(): Vector. { 105 | var tempHistory: Vector. = new Vector.(); 106 | 107 | for each(var myList: MyList in history) { 108 | tempHistory.push(new MyList(myList.myListUrl, myList.myListName, false, null)); 109 | } 110 | 111 | return tempHistory; 112 | 113 | } 114 | 115 | /** 116 | * 履歴を削除します 117 | * 118 | */ 119 | public function clearHistory(): void { 120 | history.splice(0, history.length); 121 | saveHistory(); 122 | } 123 | 124 | /** 125 | * 126 | * 127 | */ 128 | public function saveHistory(): void { 129 | for (var i: int = 0; i < history.length; i++) { 130 | var myList: MyList = history[i]; 131 | ConfigManager.getInstance().setItem("myListHistoryName" + i, myList.myListName); 132 | ConfigManager.getInstance().setItem("myListHistoryUrl" + i, myList.myListUrl); 133 | } 134 | 135 | ConfigManager.getInstance().save(); 136 | 137 | } 138 | 139 | } 140 | } -------------------------------------------------------------------------------- /src/org/mineap/nndd/myList/MyListTreeItemRenderer.mxml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 0) { 17 | 18 | var count: int = searchChildren(this.data); 19 | 20 | // trace(str + ":" + count); 21 | 22 | if (count == 0) { 23 | this.label.inheritingStyles.fontWeight = "nomal"; 24 | // trace("nomal:" + str); 25 | } else { 26 | this.label.inheritingStyles.fontWeight = "bold"; 27 | // trace("bold:" + str); 28 | } 29 | 30 | } 31 | 32 | } 33 | } 34 | 35 | protected function treeitemrenderer1_dataChangeHandler(event: FlexEvent): void { 36 | // trace(event); 37 | changeBold(); 38 | } 39 | 40 | private function searchChildren(data: Object): int { 41 | 42 | var count: int = 0; 43 | 44 | if (data == null) { 45 | return count; 46 | } 47 | 48 | if (data.hasOwnProperty("label")) { 49 | var str: String = data.label as String; 50 | count += MyListManager.instance.getMyListUnPlayVideoCount(str); 51 | } 52 | 53 | if (data.hasOwnProperty("children")) { 54 | var children: Array = data.children as Array; 55 | if (children != null) { 56 | for each(var object: Object in children) { 57 | count += searchChildren(object); 58 | } 59 | } 60 | } 61 | 62 | return count; 63 | } 64 | 65 | 66 | protected function treeitemrenderer1_showHandler(event: FlexEvent): void { 67 | // TODO Auto-generated method stub 68 | changeBold(); 69 | } 70 | ]]> 71 | 72 | 73 | 74 | 75 | 76 | -------------------------------------------------------------------------------- /src/org/mineap/nndd/playList/PlayListAnalyzer.as: -------------------------------------------------------------------------------- 1 | package org.mineap.nndd.playList { 2 | import org.mineap.nndd.LogManager; 3 | import org.mineap.nndd.model.NNDDVideo; 4 | import org.mineap.nndd.util.PathMaker; 5 | 6 | /** 7 | * 8 | * @author shiraminekeisuke 9 | * 10 | */ 11 | public class PlayListAnalyzer { 12 | public function PlayListAnalyzer() { 13 | } 14 | 15 | /** 16 | * 渡された文字列をプレイリストとして解析し、その結果をVector.に格納して返します。 17 | * @param string 18 | * @return 19 | * 20 | */ 21 | public static function analyze(str: String): Vector. { 22 | 23 | var videoArray: Vector. = new Vector.(); 24 | 25 | var pattern1: RegExp = new RegExp("[^\\n]+", "ig"); 26 | var pattern2: RegExp = new RegExp("#EXTINF:([\\d]*),(.*)"); 27 | var playItems: Array = str.match(pattern1); 28 | 29 | for (var i: int = 0; i < playItems.length; i++) { 30 | try { 31 | if (playItems[i].indexOf("#") != 0) { 32 | //コメントアウト部分ではない 33 | var filePath: String = String(playItems[i]); 34 | var video: NNDDVideo = new NNDDVideo(filePath); 35 | 36 | if (filePath.indexOf("http") != -1) { 37 | var videoId: String = PathMaker.getVideoID(filePath); 38 | if (videoId != null) { 39 | var thumbImgUrl: String = PathMaker.getThumbImgUrl(videoId); 40 | if (thumbImgUrl != null) { 41 | video.thumbUrl = thumbImgUrl; 42 | } 43 | } 44 | } 45 | 46 | if ((i + 1) < playItems.length && playItems[i + 1].indexOf("#EXTINF:") != -1) { 47 | //ファイルパスの次が付加情報 48 | var array: Array = pattern2.exec(playItems[i + 1]); 49 | if (array != null) { 50 | video.time = array[1];//曲の長さ 51 | video.videoName = array[2];//タイトル 52 | } 53 | i++; 54 | } else { 55 | //違ったら次の行へ 56 | } 57 | 58 | videoArray.push(video); 59 | 60 | } 61 | } catch (error: Error) { 62 | //読み込みエラー。スキップ。 63 | LogManager.instance.addLog("プレイリストが不正:Line=[" + i + "]"); 64 | trace(error.getStackTrace()); 65 | } 66 | } 67 | 68 | return videoArray; 69 | 70 | } 71 | 72 | } 73 | } -------------------------------------------------------------------------------- /src/org/mineap/nndd/playList/PlayListDataGridBuilder.as: -------------------------------------------------------------------------------- 1 | package org.mineap.nndd.playList { 2 | import flash.filesystem.File; 3 | 4 | import mx.collections.ArrayCollection; 5 | 6 | import org.mineap.nndd.library.ILibraryManager; 7 | import org.mineap.nndd.library.LibraryManagerBuilder; 8 | import org.mineap.nndd.model.NNDDVideo; 9 | import org.mineap.nndd.util.DateUtil; 10 | import org.mineap.nndd.util.PathMaker; 11 | 12 | /** 13 | * 14 | * @author shiraminekeisuke 15 | * 16 | */ 17 | public class PlayListDataGridBuilder { 18 | 19 | private var libraryManager: ILibraryManager = LibraryManagerBuilder.instance.libraryManager; 20 | 21 | public function PlayListDataGridBuilder() { 22 | } 23 | 24 | public function build(videos: Vector.): ArrayCollection { 25 | 26 | var arrayCollection: ArrayCollection = new ArrayCollection(); 27 | 28 | for each(var video: NNDDVideo in videos) { 29 | var thumbUrl: String = ""; 30 | var creationDate: String = "-"; 31 | var pubDate: String = "-"; 32 | var playCount: Number = 0; 33 | var status: String = ""; 34 | var tempVideo: NNDDVideo = libraryManager.isExist(PathMaker.getVideoID(video.getDecodeUrl())); 35 | var time: Number = 0; 36 | 37 | if (tempVideo != null) { 38 | video = tempVideo; 39 | } 40 | 41 | if (video.uri.match(/https?:\/\//)) { 42 | status = "未ダウンロード"; 43 | } 44 | 45 | thumbUrl = video.thumbUrl; 46 | if (video.creationDate != null) { 47 | creationDate = DateUtil.getDateString(video.creationDate); 48 | } else { 49 | creationDate = "-"; 50 | } 51 | if (video.pubDate != null) { 52 | pubDate = DateUtil.getDateString(video.pubDate); 53 | } else { 54 | pubDate = "-"; 55 | } 56 | playCount = video.playCount; 57 | if (thumbUrl == "") { 58 | thumbUrl = PathMaker.createThumbImgFilePath(video.getDecodeUrl(), false); 59 | 60 | try { 61 | if (!(new File(thumbUrl).exists)) { 62 | thumbUrl = PathMaker.getThumbImgUrl(PathMaker.getVideoID(video.getDecodeUrl())); 63 | } 64 | } catch (error: Error) { 65 | thumbUrl = PathMaker.getThumbImgUrl(PathMaker.getVideoID(video.getDecodeUrl())); 66 | } 67 | } 68 | 69 | time = video.time; 70 | var timeString: String = "-"; 71 | if (time != 0) { 72 | var m: String = String(int(time / 60)); 73 | var s: String = String(int(time % 60)); 74 | if (s.length == 1) { 75 | s = "0" + s; 76 | } 77 | timeString = m + ":" + s; 78 | } 79 | 80 | arrayCollection.addItem({ 81 | dataGridColumn_thumbImage: thumbUrl, 82 | dataGridColumn_videoName: video.getVideoNameWithVideoID(), 83 | dataGridColumn_date: creationDate, 84 | dataGridColumn_pubdate: pubDate, 85 | dataGridColumn_count: playCount, 86 | dataGridColumn_condition: status, 87 | dataGridColumn_time: timeString, 88 | dataGridColumn_videoPath: video.getDecodeUrl() 89 | }); 90 | } 91 | 92 | return arrayCollection; 93 | } 94 | 95 | } 96 | } -------------------------------------------------------------------------------- /src/org/mineap/nndd/player/PatchedVideoDisplay.as: -------------------------------------------------------------------------------- 1 | package org.mineap.nndd.player { 2 | import mx.core.mx_internal; 3 | 4 | import org.osmf.media.videoClasses.VideoSurface; 5 | 6 | import spark.components.VideoDisplay; 7 | 8 | use namespace mx_internal; 9 | 10 | public class PatchedVideoDisplay extends VideoDisplay { 11 | public function get videoSurfaceObject(): VideoSurface { 12 | return this.videoPlayer.displayObject as VideoSurface; 13 | } 14 | } 15 | } 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/org/mineap/nndd/player/PlayerHistoryManager.as: -------------------------------------------------------------------------------- 1 | package org.mineap.nndd.player { 2 | import org.mineap.nndd.model.NNDDVideo; 3 | import org.mineap.nndd.util.PathMaker; 4 | 5 | /** 6 | * Playerの視聴履歴を管理します。 7 | * 8 | * @author shiraminekeisuke 9 | * 10 | */ 11 | public class PlayerHistoryManager { 12 | 13 | /** 14 | * 15 | */ 16 | private var history: Vector. = new Vector.(); 17 | 18 | /** 19 | * 20 | * 21 | */ 22 | public function PlayerHistoryManager() { 23 | } 24 | 25 | /** 26 | * 動画を追加します。 27 | * @param url 28 | * 29 | */ 30 | public function addVideoUrl(url: String): void { 31 | if (url != null) { 32 | remove(PathMaker.getVideoID(url)); 33 | history.push(new NNDDVideo(url)); 34 | while (history.length > 100) { 35 | history.shift(); 36 | } 37 | } 38 | } 39 | 40 | /** 41 | * 動画を追加します。 42 | * @param video 43 | * 44 | */ 45 | public function addVideo(video: NNDDVideo): void { 46 | if (video != null) { 47 | remove(PathMaker.getVideoID(video.getDecodeUrl())); 48 | history.push(video); 49 | while (history.length > 100) { 50 | history.shift(); 51 | } 52 | } 53 | } 54 | 55 | /** 56 | * 指定された動画IDを持つ動画をヒストリーから削除します 57 | * @param videoID 58 | * 59 | */ 60 | public function remove(videoID: String): void { 61 | for (var index: int = 0; history.length > index; index++) { 62 | if (PathMaker.getVideoID(history[index].getDecodeUrl()) == videoID) { 63 | history.splice(index, 1); 64 | return; 65 | } 66 | } 67 | return; 68 | } 69 | 70 | /** 71 | * 先頭に追加されている動画を削除し、一つ前の動画を返します。 72 | * @return 73 | * 74 | */ 75 | public function back(): NNDDVideo { 76 | // 最後に追加した(=再生中の)項目を削除 77 | if (history.length > 1) { 78 | history.splice(history.length - 1, 1); 79 | } 80 | 81 | // 新しい再生項目 82 | if (history.length > 0) { 83 | return history[history.length - 1]; 84 | } else { 85 | return null; 86 | } 87 | } 88 | 89 | } 90 | } -------------------------------------------------------------------------------- /src/org/mineap/nndd/player/model/PlayerTagString.as: -------------------------------------------------------------------------------- 1 | package org.mineap.nndd.player.model { 2 | import org.mineap.nndd.model.TagString; 3 | 4 | public class PlayerTagString extends TagString { 5 | 6 | private var _loc: String = null; 7 | 8 | private var _lock: Boolean = false; 9 | 10 | 11 | public function PlayerTagString(tag: String = null) { 12 | super(tag); 13 | } 14 | 15 | /** 16 | * ロックされているかどうか 17 | */ 18 | public function get lock(): Boolean { 19 | return _lock; 20 | } 21 | 22 | /** 23 | * @private 24 | */ 25 | public function set lock(value: Boolean): void { 26 | _lock = value; 27 | } 28 | 29 | /** 30 | * ロケール 31 | */ 32 | public function get loc(): String { 33 | return _loc; 34 | } 35 | 36 | /** 37 | * @private 38 | */ 39 | public function set loc(value: String): void { 40 | _loc = value; 41 | } 42 | 43 | } 44 | } -------------------------------------------------------------------------------- /src/org/mineap/nndd/server/IRequestProcess.as: -------------------------------------------------------------------------------- 1 | package org.mineap.nndd.server { 2 | import com.tilfin.airthttpd.server.HttpResponse; 3 | 4 | public interface IRequestProcess { 5 | /** 6 | * 7 | * リクエストに対応する処理を行った後、レスポンスに結果を格納します。 8 | * 9 | * @param requestXml 10 | * @param httpResponse 11 | * 12 | */ 13 | function process(requestXml: XML, httpResponse: HttpResponse): void; 14 | 15 | } 16 | } -------------------------------------------------------------------------------- /src/org/mineap/nndd/server/NNDDHttpService.as: -------------------------------------------------------------------------------- 1 | package org.mineap.nndd.server { 2 | import com.tilfin.airthttpd.server.HttpRequest; 3 | import com.tilfin.airthttpd.server.HttpResponse; 4 | import com.tilfin.airthttpd.services.IService; 5 | 6 | import flash.utils.ByteArray; 7 | 8 | import org.mineap.nndd.LogManager; 9 | 10 | public class NNDDHttpService implements IService { 11 | public function NNDDHttpService() { 12 | //TODO: implement function 13 | } 14 | 15 | public function doService(request: HttpRequest, response: HttpResponse): void { 16 | 17 | LogManager.instance.addLog("通信を受付:path=" + request.path + ", remoteAddress=" + 18 | response.httpConnection.socket.remoteAddress); 19 | 20 | try { 21 | 22 | if (request.path == "/NNDDServer" || request.path == "/NNDDServer/") { 23 | 24 | var byteArray: ByteArray = request.requestBody; 25 | 26 | var reqBody: String = String(byteArray); 27 | 28 | var nnddRequest: XML = new XML(reqBody); 29 | 30 | var process: IRequestProcess = RequestProcessFactory.createProcess(nnddRequest); 31 | 32 | if (process != null) { 33 | process.process(nnddRequest, response); 34 | } else { 35 | // リクエストエンティティ(=XML)の内容が妥当ではない 36 | response.statusCode = 404; 37 | return; 38 | } 39 | 40 | } else if (request.path.indexOf("/NNDDServer/") == 0 && request.path.length > 13) { 41 | 42 | if (ServerManager.instance.allowVideo) { 43 | var getVideoData: GetVideoDataProcess = new GetVideoDataProcess(); 44 | 45 | var lastIndex: int = request.path.lastIndexOf("/"); 46 | 47 | if (lastIndex < 10) { 48 | response.statusCode = 404; 49 | return; 50 | } 51 | 52 | var videoId: String = request.path.substring(lastIndex + 1); 53 | 54 | getVideoData.process(videoId, response); 55 | } else { 56 | response.statusCode = 404; 57 | return; 58 | } 59 | } else { 60 | response.statusCode = 404; 61 | LogManager.instance.addLog("リクエスト解析不可:resCode=" + response.statusCode); 62 | return; 63 | } 64 | } catch (error: Error) { 65 | trace(error.getStackTrace()); 66 | response.statusCode = 500; 67 | LogManager.instance.addLog("エラー発生:error=" + error + ", resCode=" + response.statusCode); 68 | } 69 | 70 | } 71 | } 72 | } -------------------------------------------------------------------------------- /src/org/mineap/nndd/server/RequestProcessFactory.as: -------------------------------------------------------------------------------- 1 | package org.mineap.nndd.server { 2 | import org.mineap.nndd.LogManager; 3 | import org.mineap.nndd.server.process.GetMyListByIdProcess; 4 | import org.mineap.nndd.server.process.GetMyListProcess; 5 | import org.mineap.nndd.server.process.GetVideoByIdProcess; 6 | import org.mineap.nndd.server.process.GetVideoIdListProcess; 7 | 8 | /** 9 | * 10 | * @author shiraminekeisuke 11 | * 12 | */ 13 | public class RequestProcessFactory { 14 | 15 | /** 16 | * 17 | * 18 | */ 19 | public function RequestProcessFactory() { 20 | // nothing; 21 | } 22 | 23 | /** 24 | * 指定されたリクエストに対応する処理クラスを返します。リクエストに対応する処理クラスが存在しない場合はnullを返します。 25 | * 26 | * @param request 27 | * @return 28 | * 29 | */ 30 | public static function createProcess(request: XML): IRequestProcess { 31 | 32 | if (request == null) { 33 | return null; 34 | } 35 | 36 | var type: String = request.@type; 37 | LogManager.instance.addLog("通信のリクエスト種別:" + type); 38 | 39 | if (type.indexOf(RequestType.GET_MYLIST_LIST.typeStr) != -1) { 40 | if (ServerManager.instance.allowMyList) { 41 | return new GetMyListProcess(); 42 | } 43 | } else if (type.indexOf(RequestType.GET_MYLIST_BY_ID.typeStr) != -1) { 44 | if (ServerManager.instance.allowMyList) { 45 | return new GetMyListByIdProcess(); 46 | } 47 | } else if (type.indexOf(RequestType.GET_VIDEO_ID_LIST.typeStr) != -1) { 48 | if (ServerManager.instance.allowVideo) { 49 | return new GetVideoIdListProcess(); 50 | } 51 | } else if (type.indexOf(RequestType.GET_VIDEO_BY_ID.typeStr) != -1) { 52 | if (ServerManager.instance.allowVideo) { 53 | return new GetVideoByIdProcess(); 54 | } 55 | } else { 56 | // NOT_FOUND 57 | } 58 | 59 | return null; 60 | 61 | } 62 | 63 | 64 | } 65 | } -------------------------------------------------------------------------------- /src/org/mineap/nndd/server/RequestType.as: -------------------------------------------------------------------------------- 1 | package org.mineap.nndd.server { 2 | public class RequestType { 3 | 4 | public static const GET_MYLIST_LIST: RequestType = new RequestType("GET_MYLIST_LIST"); 5 | 6 | public static const GET_MYLIST_BY_ID: RequestType = new RequestType("GET_MYLIST_BY_ID"); 7 | 8 | public static const GET_VIDEO_ID_LIST: RequestType = new RequestType("GET_VIDEO_ID_LIST"); 9 | 10 | public static const GET_VIDEO_BY_ID: RequestType = new RequestType("GET_VIDEO_BY_ID"); 11 | 12 | private var _type: String; 13 | 14 | public function RequestType(type: String) { 15 | _type = type; 16 | } 17 | 18 | public function get typeStr(): String { 19 | return _type; 20 | } 21 | 22 | } 23 | } -------------------------------------------------------------------------------- /src/org/mineap/nndd/server/ResponseType.as: -------------------------------------------------------------------------------- 1 | package org.mineap.nndd.server { 2 | public class ResponseType { 3 | 4 | public static const SUCCESS: ResponseType = new ResponseType(200); 5 | 6 | public static const REQUEST_INVALID: ResponseType = new ResponseType(400); 7 | 8 | public static const SERVER_INTERNAL_ERROR: ResponseType = new ResponseType(500); 9 | 10 | private var code: int; 11 | 12 | public function ResponseType(code: int) { 13 | this.code = code; 14 | } 15 | 16 | public function get responseCode(): int { 17 | return this.code; 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /src/org/mineap/nndd/server/ServerManager.as: -------------------------------------------------------------------------------- 1 | package org.mineap.nndd.server { 2 | import com.tilfin.airthttpd.server.HttpListener; 3 | 4 | import flash.errors.IllegalOperationError; 5 | 6 | import org.mineap.nndd.LogManager; 7 | 8 | /** 9 | * NNDDのサーバ機能を管理するクラスです 10 | * 11 | * @author shiraminekeisuke 12 | * 13 | */ 14 | public class ServerManager { 15 | 16 | private static const manager: ServerManager = new ServerManager(); 17 | 18 | private var httpListener: HttpListener = null; 19 | 20 | private var _allowVideo: Boolean = false; 21 | private var _allowMyList: Boolean = false; 22 | private var _allowSyncMyListYetPlay: Boolean = false; 23 | 24 | /** 25 | * 唯一の ServerManager のインスタンスを変えす。 26 | * @return 27 | * 28 | */ 29 | public static function get instance(): ServerManager { 30 | return manager; 31 | } 32 | 33 | /** 34 | * コンストラクタ 35 | * 36 | */ 37 | public function ServerManager() { 38 | if (manager != null) { 39 | throw new IllegalOperationError("ServerManagerはインスタンスを生成できません。"); 40 | } 41 | } 42 | 43 | /** 44 | * 指定されたポート番号で通信の待ち受けを開始します。 45 | * 46 | * @param localPort 47 | * @param allowVideo 48 | * @param allowMyList 49 | * @return 50 | * 51 | */ 52 | public function startServer( 53 | localPort: int, 54 | allowVideo: Boolean, 55 | allowMyList: Boolean, 56 | allowSyncMyListYetPlay: Boolean 57 | ): Boolean { 58 | stopServer(); 59 | 60 | this.allowMyList = allowMyList; 61 | this.allowVideo = allowVideo; 62 | this.allowSyncMyListYetPlay = allowSyncMyListYetPlay; 63 | 64 | try { 65 | 66 | httpListener = new HttpListener(httpLogCallbackFunction); 67 | 68 | httpListener.service = new NNDDHttpService(); 69 | httpListener.listen(localPort); 70 | 71 | LogManager.instance.addLog("他のNNDDからの通信待ち受けを開始しました:localPort=" + localPort); 72 | 73 | return true; 74 | 75 | } catch (error: Error) { 76 | LogManager.instance.addLog("他のNNDDからの通信待ち受けの開始に失敗:localPort=" + localPort + ", [" + error + "]"); 77 | trace(error.getStackTrace()); 78 | } 79 | 80 | return false; 81 | } 82 | 83 | /** 84 | * 85 | * @param msg 86 | * @return 87 | * 88 | */ 89 | protected function httpLogCallbackFunction(msg: String): void { 90 | trace(msg); 91 | } 92 | 93 | /** 94 | * 通信の待ち受けを終了します。 95 | * 96 | */ 97 | public function stopServer(): void { 98 | if (httpListener != null) { 99 | // 既にServerSocketが動いていたら一度閉じる 100 | try { 101 | httpListener.shutdown(); 102 | } catch (error: Error) { 103 | trace(error.getStackTrace()); 104 | } 105 | 106 | httpListener = null; 107 | 108 | } 109 | 110 | LogManager.instance.addLog("他のNNDDからの通信待ち受けを停止"); 111 | 112 | } 113 | 114 | public function get allowVideo(): Boolean { 115 | return _allowVideo; 116 | } 117 | 118 | public function set allowVideo(value: Boolean): void { 119 | _allowVideo = value; 120 | } 121 | 122 | public function get allowMyList(): Boolean { 123 | return _allowMyList; 124 | } 125 | 126 | public function set allowMyList(value: Boolean): void { 127 | _allowMyList = value; 128 | } 129 | 130 | public function get allowSyncMyListYetPlay(): Boolean { 131 | return _allowSyncMyListYetPlay; 132 | } 133 | 134 | public function set allowSyncMyListYetPlay(value: Boolean): void { 135 | _allowSyncMyListYetPlay = value; 136 | } 137 | 138 | 139 | } 140 | } -------------------------------------------------------------------------------- /src/org/mineap/nndd/server/process/GetMyListByIdProcess.as: -------------------------------------------------------------------------------- 1 | package org.mineap.nndd.server.process { 2 | import com.tilfin.airthttpd.server.HttpResponse; 3 | 4 | import org.mineap.nndd.LogManager; 5 | import org.mineap.nndd.model.RssType; 6 | import org.mineap.nndd.myList.MyListManager; 7 | import org.mineap.nndd.server.IRequestProcess; 8 | import org.mineap.nndd.server.ServerManager; 9 | 10 | /** 11 | * ID指定のマイリスト取得処理が呼ばれたときの処理 12 | * 13 | * @author shiraminekeisuke 14 | * 15 | */ 16 | public class GetMyListByIdProcess implements IRequestProcess { 17 | public function GetMyListByIdProcess() { 18 | } 19 | 20 | public function process(requestXml: XML, httpResponse: HttpResponse): void { 21 | 22 | // ID指定マイリスト取得 23 | var rssTypeStr: String = requestXml.rss.@rssType; 24 | var rssId: String = requestXml.rss.@id; 25 | 26 | // 再生済みにセットされた動画があれば取得 27 | var playedVideoIds: Vector. = new Vector.(); 28 | for each (var videoXML: XML in requestXml.rss.video) { 29 | if ("true" == videoXML.@played) { 30 | playedVideoIds.push(videoXML.@id); 31 | } 32 | } 33 | 34 | var rssType: RssType = RssType.convertStrToRssType(rssTypeStr); 35 | 36 | if (playedVideoIds.length > 0 && ServerManager.instance.allowSyncMyListYetPlay) { 37 | MyListManager.instance.updatePlayedAndSave(rssId, rssType, playedVideoIds, true); 38 | } 39 | 40 | var xml: XML = MyListManager.instance.readLocalMyList(rssId, rssType); 41 | 42 | if (xml != null) { 43 | httpResponse.body = xml.toXMLString(); 44 | httpResponse.statusCode = 200; 45 | } else { 46 | // NOT_FOUND 47 | httpResponse.statusCode = 404; 48 | } 49 | 50 | LogManager.instance.addLog("ID指定マイリスト取得要求:type=" + rssType + ", id=" + rssId + ", resCode=" + 51 | httpResponse.statusCode); 52 | 53 | } 54 | } 55 | } -------------------------------------------------------------------------------- /src/org/mineap/nndd/server/process/GetMyListProcess.as: -------------------------------------------------------------------------------- 1 | package org.mineap.nndd.server.process { 2 | import com.tilfin.airthttpd.server.HttpResponse; 3 | 4 | import org.mineap.nndd.LogManager; 5 | import org.mineap.nndd.myList.MyList; 6 | import org.mineap.nndd.myList.MyListManager; 7 | import org.mineap.nndd.server.IRequestProcess; 8 | 9 | /** 10 | * マイリスト一覧取得APIが呼ばれた場合の処理 11 | * 12 | * @author shiraminekeisuke 13 | * 14 | */ 15 | public class GetMyListProcess implements IRequestProcess { 16 | public function GetMyListProcess() { 17 | } 18 | 19 | public function process(requestXml: XML, httpResponse: HttpResponse): void { 20 | 21 | // マイリスト一覧情報取得 (フォルダ以外) 22 | var myLists: Vector. = MyListManager.instance.getAllMyList(); 23 | 24 | var nnddResponse: XML = ; 25 | for each (var myList: MyList in myLists) { 26 | var rss: XML = ; 27 | rss.@id = myList.id; 28 | rss.@rssType = myList.type.toString(); 29 | rss.@name = myList.myListName; 30 | (nnddResponse as XML).appendChild(rss); 31 | } 32 | 33 | httpResponse.body = nnddResponse.toXMLString(); 34 | httpResponse.statusCode = 200; 35 | 36 | LogManager.instance.addLog("マイリスト一覧取得要求:list.len=" + myLists.length + ", resCode=" + 37 | httpResponse.statusCode); 38 | 39 | } 40 | } 41 | } -------------------------------------------------------------------------------- /src/org/mineap/nndd/server/process/GetVideoByIdProcess.as: -------------------------------------------------------------------------------- 1 | package org.mineap.nndd.server.process { 2 | import com.tilfin.airthttpd.server.HttpResponse; 3 | 4 | import flash.filesystem.File; 5 | 6 | import org.mineap.nndd.LogManager; 7 | import org.mineap.nndd.library.ILibraryManager; 8 | import org.mineap.nndd.library.LibraryManagerBuilder; 9 | import org.mineap.nndd.model.NNDDVideo; 10 | import org.mineap.nndd.server.IRequestProcess; 11 | 12 | /** 13 | * ID指定の動画取得APIが呼ばれたときの処理です 14 | * 15 | * @author shiraminekeisuke 16 | * 17 | */ 18 | public class GetVideoByIdProcess implements IRequestProcess { 19 | public function GetVideoByIdProcess() { 20 | } 21 | 22 | public function process(requestXml: XML, httpResponse: HttpResponse): void { 23 | 24 | var libraryManager: ILibraryManager = LibraryManagerBuilder.instance.libraryManager; 25 | 26 | var videoId: String = requestXml.video.@id; 27 | 28 | if (videoId == null) { 29 | httpResponse.statusCode = 404; 30 | LogManager.instance.addLog("ID指定動画取得要求:id=" + videoId + ", resCode=" + httpResponse.statusCode); 31 | return; 32 | } 33 | 34 | var video: NNDDVideo = libraryManager.isExistByVideoId(videoId); 35 | 36 | if (video == null) { 37 | httpResponse.statusCode = 404; 38 | LogManager.instance.addLog("ID指定動画取得要求:id=" + videoId + ", resCode=" + httpResponse.statusCode); 39 | return; 40 | } 41 | 42 | var videoFile: File = video.file; 43 | 44 | if (videoFile == null || !videoFile.exists) { 45 | httpResponse.statusCode = 404; 46 | LogManager.instance.addLog("ID指定動画取得要求:id=" + videoId + ", resCode=" + httpResponse.statusCode); 47 | return; 48 | } 49 | 50 | var videoUrl: String = "http://" + httpResponse.httpRequest.host + "/NNDDServer/" + video.key; 51 | 52 | var resXML: XML = ; 53 | 54 | resXML.video.@id = video.id; 55 | resXML.video.@isEconomy = video.isEconomy; 56 | resXML.video.@videoUrl = videoUrl; 57 | if (videoFile.extension != null) { 58 | resXML.video.@extension = videoFile.extension; 59 | } 60 | resXML.video.appendChild(video.videoName); 61 | 62 | httpResponse.body = resXML.toXMLString(); 63 | httpResponse.statusCode = 200; 64 | 65 | LogManager.instance.addLog("ID指定動画取得要求:id=" + videoId + ", videoUrl:" + videoUrl + ", resCode=" + 66 | httpResponse.statusCode); 67 | 68 | } 69 | } 70 | } -------------------------------------------------------------------------------- /src/org/mineap/nndd/server/process/GetVideoIdListProcess.as: -------------------------------------------------------------------------------- 1 | package org.mineap.nndd.server.process { 2 | import com.tilfin.airthttpd.server.HttpResponse; 3 | 4 | import org.mineap.nndd.LogManager; 5 | import org.mineap.nndd.library.ILibraryManager; 6 | import org.mineap.nndd.library.LibraryManagerBuilder; 7 | import org.mineap.nndd.model.NNDDVideo; 8 | import org.mineap.nndd.server.IRequestProcess; 9 | import org.mineap.nndd.util.PathMaker; 10 | 11 | /** 12 | * 動画の一覧取得APIが呼ばれたときの処理 13 | * 14 | * @author shiraminekeisuke 15 | * 16 | */ 17 | public class GetVideoIdListProcess implements IRequestProcess { 18 | public function GetVideoIdListProcess() { 19 | } 20 | 21 | public function process(requestXml: XML, httpResponse: HttpResponse): void { 22 | var libraryManager: ILibraryManager = LibraryManagerBuilder.instance.libraryManager; 23 | 24 | var videoList: Vector. = libraryManager.getNNDDVideoArray(libraryManager.libraryDir, true); 25 | 26 | var nnddResponse: XML = ; 27 | 28 | for each(var nnddVideo: NNDDVideo in videoList) { 29 | 30 | var videoId: String = null; 31 | 32 | videoId = PathMaker.getVideoID(nnddVideo.getVideoNameWithVideoID()); 33 | 34 | if (videoId == null) { 35 | continue; 36 | } 37 | 38 | var videoXML: XML =