Több órarend támogatása, menüsor hozzáadva

Az Osztály osztályt mindenáron az Órából akarja átnevezni
This commit is contained in:
Norbi Peti 2017-02-13 13:27:20 +01:00
parent f30d18f744
commit 892c6e85da
18 changed files with 319 additions and 141 deletions

View file

@ -1,4 +1,5 @@
using HtmlAgilityPack;
using Java.Lang;
using System;
using System.Collections.Generic;
using System.IO;
@ -6,78 +7,99 @@ using System.Linq;
using System.Net;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Xml;
using System.Xml.Linq;
namespace Orarend
{
public static class API
{
{ //TODO: Beállítások: Téma (sötét, világos) (Android; platformfüggő beállítások), Előre megadott egyedi nevek használata
/// <summary>
/// <para>Visszatér az osztályok listájával, egy-egy kételemű tömbbel, az első elem az azonosító, a második a megjelenített név.</para>
/// <para>Visszatér az osztályok listájával.</para>
/// <para>Lehet null, ha még nem volt sikeres <see cref="Frissítés"/>.</para>
/// </summary>
/// <returns></returns>
public static IEnumerable<string[]> Osztályok { get; private set; }
public static Órarend AktuálisÓrarend { get; private set; }
public static Osztály[] Osztályok { get; private set; }
public static List<Órarend> Órarendek { get; } = new List<Órarend>();
/// <summary>
/// Frissíti az osztálylistát és az eredeti órarendet, első megnyitásnál, és egy órarend hozzáadásánál/szerkesztésénél, majd hetente elegendő meghívni
/// </summary>
public static async Task Frissítés()
{
AktuálisÓrarend = new Órarend { OsztályID = "12.b|2" }; //TODO: TMP
HtmlDocument doc = new HtmlDocument();
var req = WebRequest.CreateHttp("http://deri.enaplo.net/ajax/orarend/orarendoszt.php" + (AktuálisÓrarend == null ? "" : "?p=" + Uri.EscapeDataString(AktuálisÓrarend.OsztályID)));
var resp = await req.GetResponseAsync();
await Task.Run(() =>
Func<string, Task<HtmlDocument>> load = async (url) =>
{
using (var sr = new StreamReader(resp.GetResponseStream()))
HtmlDocument doc = new HtmlDocument();
var req = WebRequest.CreateHttp(url);
var resp = await req.GetResponseAsync();
await Task.Run(() =>
{
const string trtd = @"(?:\s\w+=(?:\""|\')?(?:\w|[áéóüöőúű.:;])+(?:\""|\')?)*>(?!.+?\<table(?:\s\w+?=\""?\w+\""?)*\>.+?)(.+?)(?=<\1(?:\s\w+=(?:\""|\')?(?:\w|[áéóüöőúű.:;])+(?:\""|\')?)*>)";
string html = Regex.Replace(Regex.Replace(Regex.Replace(sr.ReadToEnd(), "<th([^>]*)>((?:\\w|[áéóüöőúű.])+)(?=<)(?!\\/)", "<th$1>$2</th>"), "<(tr)" + trtd, "<$1>$2</$1>"), "<(td)" + trtd, "<$1>$2</$1>");
doc.LoadHtml(html);
}
Osztályok = doc.GetElementbyId("uok").ChildNodes.Where(node => node.HasAttributes).Select(node => new string[] { node.GetAttributeValue("value", ""), node.NextSibling.InnerText });
if (AktuálisÓrarend != null)
{
bool ahét = true;
foreach (var node in doc.GetElementbyId("oda").FirstChild.FirstChild.ChildNodes[1].ChildNodes)
using (var sr = new StreamReader(resp.GetResponseStream()))
{
switch (node.FirstChild.InnerText)
{
case "A":
ahét = true;
break;
case "B":
ahét = false;
break;
default:
{
int x = int.Parse(node.FirstChild.InnerText) - 1;
AktuálisÓrarend.Órakezdetek[x] = TimeSpan.Parse(node.FirstChild.Attributes["title"].Value.Split('-')[0].Trim());
for (int i = 0; i < 5; i++) //Napok
{ //TODO: for ciklus az egy időben tartott órákhoz
var óranode = node.ChildNodes[i + 1].FirstChild;
var óra = (ahét ? AktuálisÓrarend.ÓrákAHét : AktuálisÓrarend.ÓrákBHét)[i, x];
if (óranode.ChildNodes.Count == 0)
continue;
if (óra == null)
(ahét ? AktuálisÓrarend.ÓrákAHét : AktuálisÓrarend.ÓrákBHét)[i, x] = óra = new Óra();
var csoportok = óranode.FirstChild.InnerText.TrimEnd(':');
óra.Sorszám = x + 1;
óra.Csoportok = csoportok;
óra.Név = óranode.ChildNodes[2].Attributes["title"].Value;
óra.Azonosító = óranode.ChildNodes[2].InnerText;
óra.Terem = óranode.ChildNodes[3].InnerText.Trim(' ', '(', ')');
óra.Tanár = new Tanár
{
Azonosító = óranode.ChildNodes[4].InnerText,
Név = óranode.ChildNodes[4].Attributes["title"].Value
};
}
break;
}
}
const string trtd = @"(?:\s\w+=(?:\""|\')?(?:\w|[áéóüöőúű.:;])+(?:\""|\')?)*>(?!.+?\<table(?:\s\w+?=\""?\w+\""?)*\>.+?)(.+?)(?=<\1(?:\s\w+=(?:\""|\')?(?:\w|[áéóüöőúű.:;])+(?:\""|\')?)*>)";
string html = Regex.Replace(Regex.Replace(Regex.Replace(sr.ReadToEnd(), "<th([^>]*)>((?:\\w|[áéóüöőúű.])+)(?=<)(?!\\/)", "<th$1>$2</th>"), "<(tr)" + trtd, "<$1>$2</$1>"), "<(td)" + trtd, "<$1>$2</$1>");
doc.LoadHtml(html);
}
}
});
});
return doc;
};
if (Órarendek.Count == 0)
{
var doc = await load("http://deri.enaplo.net/ajax/orarend/orarendoszt.php");
await Task.Run(() => Osztályok = doc.GetElementbyId("uok").ChildNodes.Where(node => node.HasAttributes).Select(node => new Osztály { Azonosító = node.GetAttributeValue("value", ""), Név = node.NextSibling.InnerText }).ToArray());
}
foreach (var órarend in Órarendek)
{
var doc = await load("http://deri.enaplo.net/ajax/orarend/orarendoszt.php?p=" + Uri.EscapeDataString(órarend.Osztály.Azonosító));
await Task.Run(() =>
{
bool ahét = true;
foreach (var node in doc.GetElementbyId("oda").FirstChild.FirstChild.ChildNodes[1].ChildNodes)
{
switch (node.FirstChild.InnerText)
{
case "A":
ahét = true;
break;
case "B":
ahét = false;
break;
default:
{
int x = int.Parse(node.FirstChild.InnerText) - 1;
órarend.Órakezdetek[x] = TimeSpan.Parse(node.FirstChild.Attributes["title"].Value.Split('-')[0].Trim());
for (int i = 0; i < 5; i++) //Napok
{ //TODO: for ciklus az egy időben tartott órákhoz
var óranode = node.ChildNodes[i + 1].FirstChild;
var óra = (ahét ? órarend.ÓrákAHét : órarend.ÓrákBHét)[i, x];
if (óranode.ChildNodes.Count == 0)
continue;
if (óra == null)
(ahét ? órarend.ÓrákAHét : órarend.ÓrákBHét)[i, x] = óra = new Óra();
var csoportok = óranode.FirstChild.InnerText.TrimEnd(':');
óra.Sorszám = x + 1;
óra.Csoportok = new string[] { csoportok }; //Az állandó órarendben osztályonként csak egy csoport van egy órán
óra.Azonosító = óranode.ChildNodes[2].InnerText;
óra.TeljesNév = óranode.ChildNodes[2].Attributes["title"].Value;
óra.Terem = óranode.ChildNodes[3].InnerText.Trim(' ', '(', ')');
óra.Tanár = new Tanár
{
Azonosító = óranode.ChildNodes[4].InnerText,
Név = óranode.ChildNodes[4].Attributes["title"].Value
};
}
break;
}
}
}
});
Thread.Sleep(10);
}
}
/// <summary>
/// Frissíti a helyettesítéseket, naponta, indításkor vagy gombnyommásra frissítse (minden nap az első előtérbe kerüléskor)
/// </summary>
public static async Task HelyettesítésFrissítés()
{
}
}
}

View file

@ -35,16 +35,21 @@
</PropertyGroup>
<ItemGroup>
<Compile Include="API.cs" />
<Compile Include="Osztály.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Tanár.cs" />
<Compile Include="Óra.cs" />
<Compile Include="Órarend.cs" />
<Compile Include="ÓraTípus.cs" />
</ItemGroup>
<ItemGroup>
<Reference Include="HtmlAgilityPack, Version=1.4.9.5, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\HtmlAgilityPack.1.4.9.5\lib\portable-net45+netcore45+wpa81+wp8+MonoAndroid+MonoTouch\HtmlAgilityPack.dll</HintPath>
<Reference Include="HtmlAgilityPack, Version=1.4.9.4, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\HtmlAgilityPack.1.4.9.4\lib\portable-net45+netcore45+wpa81+wp8+MonoAndroid+MonoTouch\HtmlAgilityPack.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Mono.Android">
<HintPath>C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\MonoAndroid\v6.0\Mono.Android.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />

View file

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="HtmlAgilityPack" version="1.4.9.5" targetFramework="portable45-net45+win8+wpa81" />
<package id="HtmlAgilityPack" version="1.4.9.4" targetFramework="portable45-net45+win8+wpa81" />
</packages>

View file

@ -8,14 +8,56 @@ namespace Orarend
{
public class Óra
{
public string Azonosító { get; set; }
public string Név { get; set; }
private ÓraTípus Típus { get; set; }
public Tanár Tanár { get; set; }
public int Sorszám { get; set; }
public string Terem { get; set; }
/// <summary>
/// Az órán résztvevő csoportok, pluszjelekkel elválasztva
/// Az órán résztvevő csoportok
/// </summary>
public string Csoportok { get; set; }
public string[] Csoportok { get; set; }
public string Azonosító
{
get
{
return Típus?.Azonosító;
}
set
{
if (!ÓraTípus.Típusok.ContainsKey(value))
ÓraTípus.Típusok.Add(value, Típus = new ÓraTípus { Azonosító = value });
else
Típus = ÓraTípus.Típusok[value];
}
}
public string TeljesNév
{
get
{
return Típus?.TeljesNév;
}
set
{
if (Típus == null)
throw new InvalidOperationException("Az azonosító nincs beállítva!");
Típus.TeljesNév = value;
}
}
public string EgyediNév
{
get
{
return Típus?.EgyediNév ?? Típus?.TeljesNév;
}
set
{
if (Típus == null)
throw new InvalidOperationException("Az azonosító nincs beállítva!");
Típus.EgyediNév = value;
}
}
}
}

17
Orarend/ÓraTípus.cs Normal file
View file

@ -0,0 +1,17 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Orarend
{
public class ÓraTípus
{
public string TeljesNév { get; set; }
public string Azonosító { get; set; }
public string EgyediNév { get; set; }
public static Dictionary<string, ÓraTípus> Típusok { get; } = new Dictionary<string, ÓraTípus>();
}
}

View file

@ -17,8 +17,7 @@ namespace Orarend
/// </summary>
public Óra[,] ÓrákBHét { get; } = new Óra[6, 16];
public string Név { get; set; }
public string OsztályID { get; set; }
public string OsztályNév { get; set; }
public Osztály Osztály { get; set; }
/// <summary>
/// Egy 16 elemű tömb az órák kezdő időpontjaival
/// </summary>

View file

@ -5,32 +5,37 @@ using Android.Runtime;
using Android.Views;
using Android.Widget;
using Android.OS;
using Android.Support.V4.View;
using Orarend;
using System.Linq;
using Android.Graphics;
using Java.Lang;
namespace OrarendAndroidApp
{
[Activity(Label = "OrarendAndroidApp", MainLauncher = true, Icon = "@drawable/icon")]
[Activity(Label = "Órarend", MainLauncher = true, Icon = "@drawable/icon", Theme = "@android:style/Theme.Holo.Light")]
public class MainActivity : Activity
{
private Handler handler;
private Órarend órarend;
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
SetContentView(Resource.Layout.MainLayout);
handler = new Handler();
}
private void HelyettesítésFrissítés()
{
var table = FindViewById<TableLayout>(Resource.Id.tableLayout1);
Action<string, Color, TableRow> addCell = (text, color, tr1) =>
{
TextView textview = new TextView(this);
textview.SetText(text, TextView.BufferType.Normal);
textview.SetTextColor(color);
tr1.AddView(textview);
};
API.Frissítés().ContinueWith(t =>
{
TextView textview = new TextView(this);
textview.SetText(text, TextView.BufferType.Normal);
textview.SetTextColor(color);
tr1.AddView(textview);
};
API.HelyettesítésFrissítés().ContinueWith(t =>
{
handler.Post(() =>
{
@ -45,16 +50,56 @@ namespace OrarendAndroidApp
}
else
{
for (int j = 0; j < API.AktuálisÓrarend.ÓrákAHét.GetLength(1); j++)
for (int j = 0; j < órarend.ÓrákAHét.GetLength(1); j++)
{
TableRow tr = new TableRow(this);
for (int i = 0; i < API.AktuálisÓrarend.ÓrákAHét.GetLength(0); i++)
addCell(API.AktuálisÓrarend.ÓrákAHét[i, j] != null ? API.AktuálisÓrarend.ÓrákAHét[i, j].Név : "", Color.Aqua, tr);
for (int i = 0; i < órarend.ÓrákAHét.GetLength(0); i++)
addCell(órarend.ÓrákAHét[i, j] != null ? órarend.ÓrákAHét[i, j].EgyediNév : "", Color.Aqua, tr);
table.AddView(tr);
}
}
});
});
}
public override bool OnCreateOptionsMenu(IMenu menu)
{
MenuInflater.Inflate(Resource.Menu.main_menu_light, menu);
return base.OnCreateOptionsMenu(menu);
}
public override bool OnOptionsItemSelected(IMenuItem item)
{
switch (item.ItemId)
{
case Resource.Id.menu_refresh:
{
var bar = FindViewById<ProgressBar>(Resource.Id.progressBar1);
handler.Post(() => bar.Visibility = ViewStates.Visible);
API.HelyettesítésFrissítés().ContinueWith(t => //TODO: Megjelenítés frissítése
{
handler.Post(() => bar.Visibility = ViewStates.Gone);
});
break;
}
case Resource.Id.menu_add: //TODO
break;
case Resource.Id.menu_edit: //TODO
break;
case Resource.Id.menu_preferences: //TODO
break;
case Resource.Id.menu_fullrefresh:
{
var bar = FindViewById<ProgressBar>(Resource.Id.progressBar1);
handler.Post(() => bar.Visibility = ViewStates.Visible);
API.Frissítés().ContinueWith(t => //TODO: Megjelenítés frissítése
{
handler.Post(() => bar.Visibility = ViewStates.Gone);
});
break;
}
}
return base.OnOptionsItemSelected(item);
}
}
}

View file

@ -45,31 +45,20 @@
<Reference Include="mscorlib" />
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Xml" />
<Reference Include="Xamarin.Android.Support.v4, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Xamarin.Android.Support.v4.23.2.1\lib\MonoAndroid403\Xamarin.Android.Support.v4.dll</HintPath>
<Private>True</Private>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="MainActivity.cs" />
<Compile Include="Resources\Resource.Designer.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="ÓraPagerAdapter.cs" />
</ItemGroup>
<ItemGroup>
<None Include="GettingStarted.Xamarin" />
<None Include="packages.config" />
<None Include="Resources\AboutResources.txt" />
<None Include="Assets\AboutAssets.txt" />
<AndroidResource Include="Resources\layout\MainLayout.axml">
<SubType>AndroidResource</SubType>
</AndroidResource>
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\layout\Main.axml" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\values\Strings.xml" />
</ItemGroup>
@ -85,6 +74,21 @@
<Name>Orarend</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\menu\main_menu_light.axml" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable\ic_add_black_24dp.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable\ic_create_black_24dp.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable\ic_settings_black_24dp.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable\ic_autorenew_black_24dp.png" />
</ItemGroup>
<Import Project="$(MSBuildExtensionsPath)\Xamarin\Android\Xamarin.Android.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.

View file

@ -45,7 +45,19 @@ namespace OrarendAndroidApp
{
// aapt resource value: 0x7f020000
public const int Icon = 2130837504;
public const int ic_add_black_24dp = 2130837504;
// aapt resource value: 0x7f020001
public const int ic_autorenew_black_24dp = 2130837505;
// aapt resource value: 0x7f020002
public const int ic_create_black_24dp = 2130837506;
// aapt resource value: 0x7f020003
public const int ic_settings_black_24dp = 2130837507;
// aapt resource value: 0x7f020004
public const int Icon = 2130837508;
static Drawable()
{
@ -60,11 +72,29 @@ namespace OrarendAndroidApp
public partial class Id
{
// aapt resource value: 0x7f050001
public const int tableLayout1 = 2131034113;
// aapt resource value: 0x7f060002
public const int actionMenuView1 = 2131099650;
// aapt resource value: 0x7f050000
public const int viewpager = 2131034112;
// aapt resource value: 0x7f060004
public const int menu_add = 2131099652;
// aapt resource value: 0x7f060005
public const int menu_edit = 2131099653;
// aapt resource value: 0x7f060007
public const int menu_fullrefresh = 2131099655;
// aapt resource value: 0x7f060006
public const int menu_preferences = 2131099654;
// aapt resource value: 0x7f060003
public const int menu_refresh = 2131099651;
// aapt resource value: 0x7f060001
public const int progressBar1 = 2131099649;
// aapt resource value: 0x7f060000
public const int tableLayout1 = 2131099648;
static Id()
{
@ -80,10 +110,7 @@ namespace OrarendAndroidApp
{
// aapt resource value: 0x7f030000
public const int Main = 2130903040;
// aapt resource value: 0x7f030001
public const int MainLayout = 2130903041;
public const int MainLayout = 2130903040;
static Layout()
{
@ -95,6 +122,22 @@ namespace OrarendAndroidApp
}
}
public partial class Menu
{
// aapt resource value: 0x7f050000
public const int main_menu_light = 2131034112;
static Menu()
{
global::Android.Runtime.ResourceIdManager.UpdateIdValues();
}
private Menu()
{
}
}
public partial class String
{

Binary file not shown.

After

Width:  |  Height:  |  Size: 124 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 369 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 202 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 453 B

View file

@ -1,5 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.view.ViewPager xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent" />

View file

@ -9,5 +9,20 @@
android:id="@+id/tableLayout1"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:stretchColumns="1" />
android:stretchColumns="1"
android:scrollbars="horizontal">
<ProgressBar
style="@android:attr/progressBarStyleHorizontal"
android:id="@+id/progressBar1"
android:indeterminateTint="#00ffffff"
android:indeterminate="true"
android:indeterminateBehavior="repeat"
android:indeterminateOnly="true"
android:indeterminateTintMode="add"
android:visibility="gone" />
<ActionMenuView
android:minWidth="25px"
android:minHeight="25px"
android:id="@+id/actionMenuView1" />
</TableLayout>
</LinearLayout>

View file

@ -0,0 +1,27 @@
<?xml version="1.0" encoding="utf-8" ?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/menu_refresh"
android:icon="@drawable/ic_autorenew_black_24dp"
android:showAsAction="ifRoom"
android:title="Frissítés" />
<item
android:id="@+id/menu_add"
android:icon="@drawable/ic_add_black_24dp"
android:showAsAction="ifRoom"
android:title="Hozzáadás" />
<item
android:id="@+id/menu_edit"
android:icon="@drawable/ic_create_black_24dp"
android:showAsAction="ifRoom"
android:title="Szerkesztés" />
<item
android:id="@+id/menu_preferences"
android:icon="@drawable/ic_settings_black_24dp"
android:showAsAction="ifRoom"
android:title="Beállítások" />
<item
android:id="@+id/menu_fullrefresh"
android:showAsAction="never"
android:title="Teljes frissítés" />
</menu>

View file

@ -1,4 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Xamarin.Android.Support.v4" version="23.2.1" targetFramework="monoandroid60" />
</packages>

View file

@ -1,32 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using Android.Support.V4.View;
using Java.Lang;
namespace OrarendAndroidApp
{
public class ÓraPagerAdapter : PagerAdapter
{
public override int Count
{
get
{
throw new NotImplementedException();
}
}
public override bool IsViewFromObject(View view, Java.Lang.Object objectValue)
{
throw new NotImplementedException();
}
}
}