Skip to content

Commit

Permalink
Merge pull request #23 from dukemiller/development
Browse files Browse the repository at this point in the history
Development
  • Loading branch information
dukemiller authored Jan 5, 2017
2 parents 1c1453e + 9557e56 commit 33bc0c4
Show file tree
Hide file tree
Showing 151 changed files with 8,906 additions and 6,648 deletions.
67 changes: 46 additions & 21 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,37 +1,62 @@
# anime-downloader
A program to download and manage a collection of currently airing anime shows.

**Features**
\- Manage and track basic information about shows.
\- Search for and download any newly found episodes through a few downloading options.
\- Support for downloading from specific subgroups, and setting a whitelist subgroups to download from.
\- Set custom paths for where videos and torrent files download to and where watched files move to.
\- A basic episode file management system for moving unwatched->watched or deleting.
\- Create playlists with some file organization options.
\- MyAnimeList synchronization to your anime list (*experimental*).

**To be implemented**
\- Downloading episode ranges (e.g. 12-13)
\- Detecting and downloading two part episodes (e.g. Re: Zero 01a & 01b)
\- Searching for any episode 00 (e.g. Tales of Zestira - 00)

A program to download and manage a collection of currently airing anime shows.

### Demo

![demo](http://i.imgur.com/2Z6bugU.gif)

---

## Features

- Manage and track basic information about downloaded shows (name, episode, status, rating, optional notes, etc).
- Search for and download any newly found episodes, with a few custom options.
- Some semi advanced features, like selecting to download from specific subgroups and setting a whitelist subgroups to download from.
- Set paths to where episodes and torrent files download to and where watched files move to.
- Simple file management system for moving unwatched<->watched, deleting or creating playlists (with a few options).
- (*experimental*) MyAnimeList synchronization to your anime list. Sync your anime by going to the web view, logging in and pressing sync. It will attempt to find MyAnimeList entries for anime on your list and any further changes on the details on the anime will be marked for synchronization. Any further syncs will update your list.

## Shortcuts

**Alt+[1-8]**: Change view.
**Ctrl+X**: Close program.
**Pressing enter** while focused on a selected input (textbox, radio, anime selection) will generally have the result of attempting to save the details on the page or do the main action (anime details, settings, download, web, misc, etc.).
**Escape** will either clear out the selected input (textbox) or go back a view if in a sub-view (details of an anime).
While on the anime details page unfocused or clicking on another element to remove focus, **arrow left/page up** will go to the previous entry on the list and **arrow right/page down** will go to the next entry on the list.
While on the Anime tab and focused on the list: **Ctrl+F** will open the find bar, **Ctrl+C** will copy the selected names.

## Other notes

A lot of options and selections have tooltips. If there's a selection that doesn't make a lot of sense or is unclear, hover over the label and there could be something in the tooltip that clarifies it for you. If it still doesn't make sense, feel free to create a github issue about it and I could fix it to be more clear / rework it.

The tray provides shortcuts to the user provided folders and commonly used functions, they can be pretty useful.

## To be implemented

- Downloading episode ranges (e.g. 12-13)
- Detecting and downloading two part episodes (e.g. Re: Zero 01a & 01b)

---

### Build & Run
**Requirements:** [nuget.exe](https://dist.nuget.org/win-x86-commandline/latest/nuget.exe) on PATH, Visual Studio 2015 and/or C# 6.0 Roslyn Compiler

**Requirements:** [nuget.exe](https://dist.nuget.org/win-x86-commandline/latest/nuget.exe) on PATH, Visual Studio 2015 and/or C# 6.0 Roslyn Compiler
**Optional:** Devenv (Visual Studio 2015) on PATH

```
git clone https://github.com/dukemiller/anime-downloader.git
cd anime-downloader
nuget install anime-downloader\packages.config -OutputDirectory packages
```
**Building with Devenv (CLI):** ```devenv anime-downloader.sln /Build```
**Building with Visual Studio:** Open (ctrl-shift-o) "anime-downloader.sln", Build Solution (ctrl-shift-b)
```

**Building with Devenv (CLI):** ``devenv anime-downloader.sln /Build``
**Building with Visual Studio:** Open (Ctrl+Shift+O) "anime-downloader.sln", Build Solution (Ctrl+Shift+B)

An "anime-downloader.exe" artifact will be created in the parent anime-downloader folder.

---

### Notes
\- This is my first larger sized application using WPF, based on very little knowledge of both C# and WPF. That is to say a lot of bad practices are probably in the code.
\- Not tested on other platforms other than **Windows**, and im assuming that since it's WPF based that the support for Mono for Linux/Mac is pretty nonexistant.
+ I started this off as my first application and went through a lot of changes (Delegating every event in the MainWindow.xaml.cs + using x:Name in xaml to alter in code behind, to some view binding and binding the datacontext to {View}.xaml.cs and making the "Settings" classes statically accessable from MainWindow.xaml.cs, to actually using ViewModels and some MVVM practices). What i'm saying is that there's probably some bugs here and there that need fixing and weird behaviors, so throw up a github issue and i'll fix it pretty quickly.
+ Not tested on other platforms other than **Windows**, but the GUI is WPF based so that's pretty much the end of the line for Mac/Linux support at the moment. In the future, I could extend the project to have all the services and models be their own solution and use something like GTK# for cross platform support given the demand.
8 changes: 8 additions & 0 deletions anime-downloader.Tests/Credentials.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
namespace anime_downloader.Tests
{
public static partial class Credentials
{
public static readonly string MyAnimeListName = "";
public static readonly string MyAnimeListPassword = "";
}
}
92 changes: 92 additions & 0 deletions anime-downloader.Tests/MyAnimeListTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
using System.Threading.Tasks;
using anime_downloader.Models;
using anime_downloader.Models.Configurations;
using anime_downloader.Services;
using anime_downloader.Services.Interfaces;
using anime_downloader.Tests.Services;
using NUnit.Framework;

namespace anime_downloader.Tests
{
[TestFixture]
public class MyAnimeListTests
{
private ISettingsService _settings;
private IAnimeService _animes;
private IMyAnimeListService _mal;

[SetUp]
public void Init()
{
_settings = new MockXmlSettingsService
{
MyAnimeListConfig =
new MyAnimeListConfiguration
{
Username = Credentials.MyAnimeListName,
Password = Credentials.MyAnimeListPassword
}
};
_animes = new MockAnimeService();
_mal = new MyAnimeListService(_settings, _animes);
}

private async Task TestId(string name, string expectedId)
{
var anime = new Anime { Name = name };
var result = await _mal.GetId(anime);
Assert.IsTrue(result);
Assert.AreEqual(anime.MyAnimeList.Id, expectedId);
}

/// <summary>
/// Test that the myanimelist id finds the correct anime
/// on selected general cases
/// </summary>
[Test]
public async Task FindIdTest()
{
// exclamations
await TestId("Yuri!!! on Ice", "32995");

// forward slash & colon
await TestId("Fate/Grand Order: First Order", "34321");

// long name, colon
await TestId("Nejimaki Seirei Senki: Tenkyou No Alderamin", "31764");

// parenthesis
await TestId("Gi(A)Rlish Number", "32607");

// semicolon
await TestId("Occultic;Nine", "32962");

// number, period, long name, second cour
await TestId("12-Sai.: Chicchana Mune No Tokimeki 2Nd Season", "33419");

// reboot, year in title
await TestId("Berserk (2016)", "32379");

// very short title, close to other series names, meta information in title
await TestId("Days (TV)", "32494");

// weird symbol, meta information
await TestId("Saiki Kusuo No Ψ-Nan (TV)", "33255");

// name very close to OVA, meta information in title
await TestId("Big Order (TV)", "31904");

// this should be pretty hard to fail
await TestId("Kiznaiver", "31798");

// short name
await TestId("Ajin", "31580");

// second cour, short name
await TestId("Gate: Jieitai Kanochi Nite, Kaku Tatakaeri 2Nd Season", "31637");

// first cour
await TestId("Fate/Stay Night: Unlimited Blade Works", "22297");
}
}
}
36 changes: 36 additions & 0 deletions anime-downloader.Tests/Properties/AssemblyInfo.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;

// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("anime-downloader.Tests")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("anime-downloader.Tests")]
[assembly: AssemblyCopyright("Copyright © 2017")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]

// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]

// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("54c944ea-8a61-41cc-9b9a-f53cf0cfeb3c")]

// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
53 changes: 53 additions & 0 deletions anime-downloader.Tests/Services/MockAnimeService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
using System;
using System.Collections.Generic;
using anime_downloader.Models;
using anime_downloader.Services.Interfaces;

namespace anime_downloader.Tests.Services
{
public class MockAnimeService: IAnimeService
{
public IEnumerable<Anime> Animes { get; }

public IEnumerable<Anime> AiringAndWatching { get; }

public IEnumerable<Anime> NeedsUpdates { get; }

public IEnumerable<Anime> FilteredAndSorted()
{
throw new NotImplementedException();
}

public IEnumerable<Anime> FullyWatched()
{
throw new NotImplementedException();
}

public IEnumerable<Anime> AiringAndWatchingAndNotCompleted()
{
throw new NotImplementedException();
}

public IEnumerable<Anime> HasId { get; }

public void Add(Anime anime)
{
throw new NotImplementedException();
}

public void Remove(Anime anime)
{
throw new NotImplementedException();
}

public void Remove(string name)
{
throw new NotImplementedException();
}

public Anime ClosestAnime(string name)
{
throw new NotImplementedException();
}
}
}
20 changes: 20 additions & 0 deletions anime-downloader.Tests/Services/MockXmlSettingsService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
using System.Collections.Generic;
using anime_downloader.Models;
using anime_downloader.Models.Configurations;
using anime_downloader.Services.Interfaces;

namespace anime_downloader.Tests.Services
{
public class MockXmlSettingsService: ISettingsService
{
public PathConfiguration PathConfig { get; set; } = new PathConfiguration();
public FlagConfiguration FlagConfig { get; set; } = new FlagConfiguration();
public MyAnimeListConfiguration MyAnimeListConfig { get; set; } = new MyAnimeListConfiguration();
public string SortBy { get; set; } = "";
public string FilterBy { get; set; } = "";
public List<string> Subgroups { get; set; } = new List<string>();
public List<Anime> Animes { get; set; } = new List<Anime>();
public bool CrucialDirectoriesExist() => true;
public void Save() {}
}
}
Loading

0 comments on commit 33bc0c4

Please sign in to comment.