Lebokeiss OÜ
Kodutöö aines "Võrgurakendused II: hajussüsteemide ehitamine"
Meeskond
- Joonas Jõeleht - Projektijuht
- Karell Veskimeister
- Kerli Edasi
- Iris Tambaum
- Timo Lanno
Idee
Luua rakendus, mis võimaldab kaardisõltlastel salvestada mänguskoore.
Kasutatav .NET tehnoloogia
- ASP.NET Web API
- ASP.NET MVC
- ASP.NET Identity
- Entity Framework Code First
Analüüs
Meie API eesmärk on hoida andmeid kaardimängude tulemuste kohta. Mõeldud on kaardimänge, kus toimub mitu seeriat ning pärast igat seeriat on punktiarvestus. Meie eesmärk ongi just nende punktide arvestusega tegelemine. Andmebaas võimaldab endas hoida erinevate kaardimängude andmeid, s.t et andmebaas ei ole vaid ühe kaardimängupõhine. Andmebaas ei hoia endas kogu mängu käiku (kuskile ei salvestu, mis kaardid kellelgi spetsiifiliselt käes on) vaid ainult andmeid tulemuste kohta (iga roundi lõpus olevad seisud). Lisaks on võimalik küsida mängijate, mängude jne statistikat.
Rakenduse sisu
Rakenduses on olemas järgmised võimalused (Must have):
- Andmete väljastamine JSON,XML
- CRUD õigused kasutajapõhiselt
- CRUD õigused API-KEY kohaselt
- Kasutajapõhine ajalugu
- Gentleman kaardimängu tugi 100% (saab kasutada täielikult)
CRUD õigused kasutajapõhiselt:
- Mängutüüpide andmete töötlemine
- Mängu andmete töötlemine
- Jooksvalt mänguseisude töötlemine
CRUD õigused API-KEY kohaselt:
- Jooksvalt mänguseisude töötlemine
Selgitus: API-KEY omab maksimaalselt samu õigusi mis kasutaja, kuid üldjuhul on temale antud vähem õigusi.
Rakenduses võiksid olla lisavõimalused (Should have):
- Statistikaarvutamise võimalused
- Kaardimängu Tuhat tugi
- Voice recording and score adding by voice
- Andmete väljastamine: Excel (kirjutame oma mappimismooduli)
Valmis programm
Semestri töö tulemusena valmis veidi analüüsisitust erinev rakendus, ent puuduva funktsionaalsuse katsime uue funktsionaalsusega..
Api-keyga sisselogemise asemel lisasime funktsionaalsuse, et igal inimesel on sõbralist ning kasutaja saab nende tulemusi näha.
Samuti toetab valminud klientrakendust mitmekeelsust, ning artiklite tõlked tulevad ka üle api.
Rakenduse installimine
Tõmmata alla failid siit. Link kohe ilmub.
Pisike juhend klientrakendusel vajaminevate js failide installimiseks.
- installida nodejs (koos npm-iga)
- installida git https://git-for-windows.github.io #(vajalik, et bower saaks vajalikud paketid alla tõmmata)
- kliendi web kausta teha alamkaust bower_components (kui pole veel)
- npm install -g bower #package manager to web
- npm install -g cldr-data-downloader # A Node.js download tool for Unicode CLDR JSON data.
- bower install #(käivitada klientrakenduse põhikaustas)
- node %USERPROFILE%\AppData\Roaming\npm\node_modules\cldr-data-downloader\bin\download.js -i Web\bower_components\cldr-data\index.json -o Web\bower_components\cldr-data\
- Kui nugget-packages ei tööta, siis --> Tools->NuGet package manager>package manager settings>package manager source ning linnuke microsoft net ette
Palju õnne, teil on töötav rakendus. Käivitada server ja peale seda klient! olemasolev konto, millega sisse logida lebo@lebo.ee password: admin
XML/XSD/XSLT
XML
<?xml version="1.0" standalone="yes"?>
<Shop>
<Users>
<User id="9999999" registerDate="2005-01-01T08:05:07" disabled="false" birthDate="1950-03-09T16:05:07.123" countryCode="EE">
<Username><![CDATA[Praam]]></Username>
<Email><![CDATA[praam22@praam.ee]]></Email>
<Description><![CDATA[Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.]]></Description>
<Pictures>
<Picture id="7" visible="true" favorite="false">
<Description><![CDATA[Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.]]></Description>
<Tags>
<Tag sortOrder="1" visibleToAll="true"><![CDATA[Landscape]]></Tag>
<Tag sortOrder="3" visibleToAll="true"><![CDATA[#lit]]></Tag>
<Tag sortOrder="2" visibleToAll="true"><![CDATA[Perfectionist]]></Tag>
</Tags>
</Picture>
<Picture id="777" visible="true" favorite="false">
<Description><![CDATA[Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.]]></Description>
<Tags>
<Tag sortOrder="1" visibleToAll="true"><![CDATA[Butterflies]]></Tag>
</Tags>
</Picture>
<Picture id="888" visible="true" favorite="false">
<Description><![CDATA[Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.]]></Description>
<Tags>
<Tag sortOrder="1" visibleToAll="true"><![CDATA[Funny]]></Tag>
<Tag sortOrder="2" visibleToAll="true"><![CDATA[Hilarious]]></Tag>
</Tags>
</Picture>
</Pictures>
<Tags>
<Tag sortOrder="2"><![CDATA[Anime]]></Tag>
<Tag sortOrder="1"><![CDATA[Realistic]]></Tag>
</Tags>
</User>
<User id="001" registerDate="2002-02-09T09:21:11" disabled="false" birthDate="2002-02-09T09:21:11.321" countryCode="EE">
<Username><![CDATA[Karell]]></Username>
<Email><![CDATA[vutlar@ee.ee]]></Email>
<Description><![CDATA[Karells desc]]></Description>
<Pictures>
<Picture id="880" visible="true" favorite="false">
<Description><![CDATA[This is my 4th attempt at creating anime zoomout by using photo of geographical a location]]></Description>
<Tags>
<Tag sortOrder="1" visibleToAll="true"><![CDATA[Anime]]></Tag>
<Tag sortOrder="2" visibleToAll="true"> <![CDATA[Nature]]></Tag>
<Tag sortOrder="4" visibleToAll="true"><![CDATA[Geography]]></Tag>
<Tag sortOrder="3" visibleToAll="true"><![CDATA[Photography]]></Tag>
<Tag sortOrder="5" visibleToAll="true"><![CDATA[Tracing]]></Tag>
</Tags>
</Picture>
<Picture id="280" visible="true" favorite="false">
<Description><![CDATA[Guide photo how i trace photos]]></Description>
<Tags>
<Tag sortOrder="2" visibleToAll="true"><![CDATA[Photography]]></Tag>
<Tag sortOrder="1" visibleToAll="true"><![CDATA[Tracing]]></Tag>
</Tags>
</Picture>
</Pictures>
<Tags>
<Tag sortOrder="1"><![CDATA[Anime]]></Tag>
<Tag sortOrder="2"><![CDATA[Tracing]]></Tag>
</Tags>
</User>
<User id="3" registerDate="2016-03-09T16:05:07" disabled="false" birthDate="1996-03-09T16:05:07.123" countryCode="EE">
<Username><![CDATA[ParanoidZebra]]></Username>
<Email><![CDATA[ParanoidZebra@zebra.zoo]]></Email>
<Description><![CDATA[Hello world]]></Description>
<Pictures>
<Picture id="31" visible="true" favorite="true">
<Description><![CDATA[]]></Description>
<Tags>
<Tag sortOrder="1" visibleToAll="true"><![CDATA[Anime]]></Tag>
<Tag sortOrder="2" visibleToAll="true"><![CDATA[Zebra]]></Tag>
<Tag sortOrder="3" visibleToAll="true"><![CDATA[Sun]]></Tag>
</Tags>
</Picture>
<Picture id="32" visible="true" favorite="true">
<Description><![CDATA[]]></Description>
<Tags>
<Tag sortOrder="31" visibleToAll="true"><![CDATA[Anime]]></Tag>
<Tag sortOrder="3" visibleToAll="true"><![CDATA[Zebra]]></Tag>
</Tags>
</Picture>
<Picture id="33" visible="true" favorite="true">
<Description><![CDATA[]]></Description>
<Tags>
<Tag sortOrder="1" visibleToAll="true"><![CDATA[Anime]]></Tag>
<Tag sortOrder="2" visibleToAll="true"><![CDATA[Zebra]]></Tag>
<Tag sortOrder="3" visibleToAll="true"><![CDATA[Privatetag]]></Tag>
</Tags>
</Picture>
</Pictures>
<Tags>
<Tag sortOrder="2"></Tag>
</Tags>
</User>
</Users>
<Pictures>
<Picture id="31" dateCompleted="2008-03-09T16:05:07" makerId="3" buyerId="9999999">
<Name><![CDATA[Drunk zebra and sunset]]></Name>
<LocationUrl><![CDATA[https://upload.wikimedia.org/wikipedia/commons/8/83/Zebra_Botswana_edit02.jpg]]></LocationUrl>
</Picture>
<Picture id="32" dateCompleted="2008-03-09T16:05:07.123" makerId="3" buyerId="0">
<Name><![CDATA[Not so drunk zebra and sunset]]></Name>
<LocationUrl><![CDATA[https://upload.wikimedia.org/wikipedia/commons/8/83/Zebra_Botswana_edit02.jpg]]></LocationUrl>
</Picture>
<Picture id="33" dateCompleted="2008-03-09T16:05:07.123" makerId="3" buyerId="0">
<Name><![CDATA[No Zebra and sunse]]></Name>
<LocationUrl><![CDATA[https://upload.wikimedia.org/wikipedia/commons/8/83/Zebra_Botswana_edit02.jpg]]></LocationUrl>
</Picture>
<Picture id="7" dateCompleted="2008-03-09T16:05:07.123" makerId="9999999" buyerId="0">
<Name><![CDATA[Landscape]]></Name>
<LocationUrl><![CDATA[http://i.imgur.com/IL5qx77r.jpg]]></LocationUrl>
</Picture>
<Picture id="777" dateCompleted="2012-03-09T12:33:07.678" makerId="9999999" buyerId="0">
<Name><![CDATA[Purple Butterfly]]></Name>
<LocationUrl><![CDATA[http://i.imgur.com/tJvg7Qd.jpg]]></LocationUrl>
</Picture>
<Picture id="888" dateCompleted="2016-03-09T11:11:11.555" makerId="9999999" buyerId="0">
<Name><![CDATA[Owl how-to]]></Name>
<LocationUrl><![CDATA[http://i.imgur.com/kArLDrg.jpg]]></LocationUrl>
</Picture>
<Picture id="880" dateCompleted="2016-02-09T09:21:11.321" makerId="999992" buyerId="0">
<Name><![CDATA[Anime scenery]]></Name>
<LocationUrl><![CDATA[https://s-media-cache-ak0.pinimg.com/736x/c8/f8/a5/c8f8a53e2831a5917fbedaac2f08e265.jpg]]></LocationUrl>
</Picture>
<Picture id="280" dateCompleted="2016-01-02T19:21:11.321" makerId="299992" buyerId="0">
<Name><![CDATA[Trace how-to]]></Name>
<LocationUrl><![CDATA[https://s-media-cache-ak0.pinimg.com/736x/c8/f8/a5/c8f8a53e2831a5917fbedaac2f08e265.jpg]]></LocationUrl>
</Picture>
</Pictures>
</Shop>
XSD
<?xml version="1.0" encoding="utf-8"?>
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:simpleType name="ValidateEmail">
<xs:restriction base="xs:string">
<xs:pattern value="[A-Za-z0-9_]+([-+.'][A-Za-z0-9_]+)*@[A-Za-z0-9_]+([-.][A-Za-z0-9_]+)*\.[A-Za-z0-9_]+([-.][A-Za-z0-9_]+)*" />
<xs:minLength value="6"/>
<xs:maxLength value="64"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="CountryCodeRestr">
<xs:restriction base="xs:string">
<xs:minLength value="2"/>
<xs:maxLength value="3"/>
</xs:restriction>
</xs:simpleType>
<xs:element name="Shop">
<xs:complexType>
<xs:sequence>
<xs:element name="Users">
<xs:complexType>
<xs:sequence>
<xs:element maxOccurs="unbounded" name="User">
<xs:complexType>
<xs:sequence>
<xs:element name="Username">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:minLength value="5"/>
<xs:maxLength value="32"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
<xs:element name="Email" type="ValidateEmail" />
<xs:element name="Description" >
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:maxLength value="10000"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
<xs:element name="Pictures">
<xs:complexType>
<xs:sequence>
<xs:element maxOccurs="unbounded" name="Picture">
<xs:complexType>
<xs:sequence>
<xs:element name="Description">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:maxLength value="5000"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
<xs:element name="Tags">
<xs:complexType>
<xs:sequence>
<xs:element maxOccurs="50" name="Tag">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute name="sortOrder" type="xs:unsignedByte" use="required" />
<xs:attribute name="visibleToAll" type="xs:boolean" use="required" />
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="id" type="xs:unsignedLong" use="required" />
<xs:attribute name="visible" type="xs:boolean" use="required" />
<xs:attribute name="favorite" type="xs:boolean" use="required" />
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="Tags">
<xs:complexType>
<xs:sequence>
<xs:element maxOccurs="50" name="Tag" >
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute name="sortOrder" type="xs:unsignedByte" use="required"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="id" type="xs:unsignedLong" use="required" />
<xs:attribute name="registerDate" type="xs:dateTime" use="required" />
<xs:attribute name="disabled" type="xs:boolean" use="required" />
<xs:attribute name="birthDate" type="xs:dateTime" use="required" />
<xs:attribute name="countryCode" type="CountryCodeRestr" use="required" />
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="Pictures">
<xs:complexType>
<xs:sequence>
<xs:element maxOccurs="unbounded" name="Picture">
<xs:complexType>
<xs:sequence>
<xs:element name="Name">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:minLength value="1"/>
<xs:maxLength value="512"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
<xs:element name="LocationUrl">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:minLength value="1"/>
<xs:maxLength value="5000"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
</xs:sequence>
<xs:attribute name="id" type="xs:unsignedLong" use="required" />
<xs:attribute name="dateCompleted" type="xs:dateTime" use="required" />
<xs:attribute name="makerId" type="xs:unsignedLong" use="required" />
<xs:attribute name="buyerId" type="xs:unsignedLong" use="optional" default="0" />
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
XSLT(html)
Tulemus: [1]
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl">
<xsl:output method="html" indent="yes"/>
<xsl:template match="/">
<html>
<head>
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" integrity="sha384-1q8mTJOASx8j1Au+a5WDVnPi2lkFfwwEAa8hDDdjZlpLegxhjVME1fgjWPGmkzs7" crossorigin="anonymous" />
<!-- Optional theme -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap-theme.min.css" integrity="sha384-fLW2N01lMqjakBkx3l/M9EahuwpSfeNvV63J5ezn3uZzapT0u7EYsXMjQV+0En5r" crossorigin="anonymous" />
<!-- Latest compiled and minified JavaScript -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js" integrity="sha384-0mSbJDEHialfmuBBQP6A4Qrprq5OVfW37PRR3j5ELqxss1yVqOtnepnHVP9aJ7xS" crossorigin="anonymous"></script>
</head>
<body>
<div class="container">
<div class="page-header">
<h2>Our users: </h2>
</div>
<xsl:for-each select="/Shop/Users/User">
<h3>
<xsl:value-of select="Username"/>
<xsl:text> - </xsl:text>
<small><xsl:value-of select="Email"/></small>
</h3>
<xsl:for-each select="Tags/Tag">
<span class="label label-info"><xsl:value-of select="."/></span>
</xsl:for-each>
<br/>
<table class="table table-hover">
<thead>
<tr>
<th>Register date</th>
<th>Birthday</th>
<th>Country code</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<xsl:variable name="dt" select="@registerDate"/>
<xsl:value-of select="concat(
substring($dt, 9, 2),
'/',
substring($dt, 6, 2),
'/',
substring($dt, 1, 4)
)"/>
</td>
<td>
<xsl:variable name="dt" select="@birthDate"/>
<xsl:value-of select="concat(
substring($dt, 9, 2),
'/',
substring($dt, 6, 2),
'/',
substring($dt, 1, 4)
)"/>
</td>
<td>
<xsl:value-of select="@countryCode"/>
</td>
</tr>
</tbody>
</table>
<h4>User description:</h4>
<p align="justify">
<xsl:value-of select="Description"/>
</p>
<br/>
<h4>User pictures:</h4>
<xsl:for-each select="Pictures/Picture">
<xsl:variable name="picId" select="@id"/>
<xsl:for-each select="/Shop/Pictures/Picture">
<xsl:if test = "$picId = @id">
<b><xsl:value-of select='Name' /></b>
<br/>
<img height="50px">
<xsl:attribute name="src">
<xsl:value-of select='LocationUrl' />
</xsl:attribute>
<xsl:attribute name="alt">
<xsl:value-of select='Name' />
</xsl:attribute>
</img>
</xsl:if>
</xsl:for-each>
<br/>
<xsl:for-each select="Tags/Tag">
<span class="label label-info">
<xsl:value-of select="."/>
</span>
</xsl:for-each>
<h5>Picture description:</h5>
<p align="justify">
<xsl:value-of select="Description"/>
</p>
<br/>
</xsl:for-each>
<br/>
</xsl:for-each>
</div>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
XSLT(xml)
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/">
<Root>
<AllUsers>
<xsl:for-each select="/Shop/Users/User">
<User>
<xsl:attribute name="id">
<xsl:value-of select='@id' />
</xsl:attribute>
<xsl:value-of select="Username"/>
</User>
</xsl:for-each>
</AllUsers>
<AllPictures>
<xsl:for-each select="/Shop/Pictures/Picture">
<Picture>
<xsl:attribute name="id">
<xsl:value-of select='@id' />
</xsl:attribute>
<xsl:choose>
<xsl:when test = "@buyerId != 0">
<xsl:attribute name="IsSold">
<xsl:text>true</xsl:text>
</xsl:attribute>
</xsl:when>
<xsl:otherwise>
<xsl:attribute name="IsSold">
<xsl:text>false</xsl:text>
</xsl:attribute>
</xsl:otherwise>
</xsl:choose>
<Location>
<xsl:value-of select="LocationUrl"/>
</Location>
</Picture>
</xsl:for-each>
</AllPictures>
</Root>
</xsl:template>
</xsl:stylesheet>
Logi
12.06.16
- Sai tehtud ühine koodismisralli..nüüd teame unepealt mis HTTP statuskood kuhu läeb
10.06.16
- Kuigi wikis on vahepeal tuul puhunud rakendus siiski on lõpuks pildi ette saadud.. Kaitsesime oma tehtud tööd ja selgus, et saada maksimum tulemus peame veidi veel pingutama. Jaksu!
17.04.16
19.03.16
- Tegime valmis XMLi, XSD ja XSLT-d
07.03.16