[RELEASE] RexiMemo: Open Source Edition

This commit is contained in:
Rekushi authored and GitHub committed 2026-09-15 23:07:13 +01:00
1 parent 5e2acc31c5
commit a438dfc231
45 files changed
+8516 -169

No files matched your search

+830
View File
@@ -0,0 +1,830 @@
@charset "UTF-8";
table.profbox {
background-color: #82c300;
color: #ffffff;
}
div.prof_out {
margin: 0 11px 0 11px;
background-color: #82c300;
border-style: solid;
border-width: 0 1px 0 1px;
border-color: #82c300;
}
span.more-f{
color: #ffffff;
}
div.notice2 {
margin:0 11px 5px 11px;
padding:5px;
border-style:solid;
border-width:1px;
border-color:#82c300;
background-color:#fbfbfb;
}
span.url{
text-decoration:underline;
}
span.comptxt {
color:#ff8a00;
}
span.star0 {
color:#fdc556;
}
span.star1 {
color:#138200;
}
span.star2 {
color:#ff455c;
}
span.star3 {
color:#00b0f9;
}
span.star4 {
color:#a411b9;
}
span.star0c {
color:#fdc556;
}
span.star1c {
color:#138200;
}
span.star2c {
color:#ff455c;
}
span.star3c {
color:#00b0f9;
}
span.star4c {
color:#a411b9;
}
span.orange{
color: #ff8d45;
}
span.green {
color: #82c300;
}
span.gray{
color: #666666;
}
span.white {
color:#FFFFFF;
}
html {
margin:0;
padding:0;
}
body {
color:#333333;
margin:0;
padding:0;
}
div.title {
margin:0 7px 0 7px;
padding:7px 5px 7px 5px;
border-style:solid;
border-width:0 0 1px 0;
border-color:#CCCCCC;
}
div.description {
margin:0 7px 0 7px;
padding:7px 5px 7px 5px;
border-style:solid;
border-width:0 0 1px 0;
border-color:#CCCCCC;
}
div.hr {
border-style:solid;
border-width:0 0 1px 0;
border-color:#CCCCCC;
}
div.hr-tab {
border-style:solid;
border-width:0 0 1px 0;
border-color:#82c300;
}
span.timestamp {
color:#999999;
}
a.timestamp {
color:#999999;
}
a.violation {
color:#333333;
}
div.box {
padding:7px;
border-style:solid;
border-width:1px;
border-color:#CCCCCC;
background-color:#FFFFFF;
}
div.more {
margin:7px 0 0 0;
}
div.pager {
padding:5px;
}
div.num {
margin:5px;
padding:5px;
border-style:solid;
border-width:1px;
border-color:#CCCCCC;
background-color:#FFFFFF;
}
span.new {
color: #cc0000;
}
span.price {
color: #92cb22;
}
span.date {
color: #cccccc;
}
table.detail{
margin:0 7px 0 7px;
}
table.fullsize {
margin:0;
}
div.item-term {
padding:3px 0 3px 5px;
}
div.item-value {
padding:3px 5px 3px 0;
}
div.item-text {
padding:3px 5px 3px 15px;
}
div.item-tcom {
padding: 3px 5px 0 5px;
}
div.item-com {
padding: 0 5px 0 5px;
}
div.td-body {
padding:3px 5px 3px 5px;
}
div.comlist {
background-color:#FFFFFF;
}
div.comment-text {
padding:3px 5px 5px 15px;
}
div.comment-memo {
padding:0 0 0 15px;
}
div.staff {
color:#FFFFFF;
background-color:#1a1a1a;
}
a.staffnam {
color:#FFFFFF;
}
div.notice {
width:226px;
margin:7px 7px 3px 7px;
padding:5px;
border-style:solid;
border-width:1px;
border-color:#BCCDED;
background-color:#E5EEFE;
}
div.colorstar {
margin:7px 0 7px 0;
}
div.code-box{
width:226px;
margin:7px 0 0 0;
padding:5px;
border-style:solid;
border-width:1px;
border-color:#BCCDED;
background-color:#E5EEFE;
}
div.code-data{
margin:7px 0 7px 0;
}
div.mail-reply {
width:226px;
margin:7px 7px 2px 7px;
padding:5px;
border-style:solid;
border-width:1px;
border-color:#BCCDED;
background-color:#E5EEFE;
}
div.lett_txt {
margin: 0 11px 0 11px;
border-style:solid;
border-width:0 2px 0 2px;
border-color:#92d300;
background-color:#ffffff;
}
div.lett_to {
margin: 0 11px 0 11px;
background-color:#92d300;
color:#ffffff;
padding: 1px 0 6px 5px;
}
div.pad0{
padding: 0 0 0 0;
}
div.pad5t{
padding: 5px 0 0 0;
}
div.pad5b{
padding: 0 0 5px 0;
}
div.pad1b{
padding: 0 0 1px 0;
}
div.pad2b{
padding: 0 0 2px 0;
}
div.pad2{
padding: 2px 2px 2px 2px;
}
div.pad5{
padding: 5px 5px 5px 5px;
}
div.pad0-5{
padding: 0 5px 0 5px;
}
td.pad2{
padding: 2px 2px 2px 2px;
}
div.pad3-5{
padding: 3px 5px 3px 5px;
}
div.lett_from{
padding: 3px 11px 3px 0;
}
div.pad11{
padding: 11px 11px 11px 11px;
}
div.pad5-11{
padding: 5px 11px 5px 11px;
}
div.pad10b{
padding: 0 0 10px 0;
}
div.pad20b{
padding: 0 0 20px 0;
}
div.mar0-7{
margin: 0px 7px 0px 7px;
}
div.mar0-11{
margin: 0px 11px 0px 11px;
}
div.mar0{
margin: 0px 0px 0px 0px;
}
div.mar5 {
margin: 5px 5px 5px 5px;
}
div.yaritori{
margin: 0 11px 0 11px;
background-color:#ffffff;
border-style:solid;
border-width:0 2px 0 2px;
border-color:#92d300;
}
div.gr-tit{
margin: 0 11px 0 11px;
background-color:#92d300;
color:#ffffff;
}
div.kadomaru{
margin: 0 11px 0 11px;
}
div.lett-note{
margin: 5px 11px 5px 11px;
padding:5px;
border-style:solid;
border-width:1px;
border-color:#92d300;
background-color:#ffffff;
}
div.pk{
background-color:#ff3ab7;
}
div.blue{
background-color:#3acfff;
}
div.gray{
background-color:#cccccc;
}
div.gray_box{
padding:5px;
border-style:solid;
border-width:1px;
border-color:#cccccc;
background-color:#ffffff;
}
div.vio-intro {
width:240px;
padding:7px 0 7px 7px;
}
div.vio-memo {
padding:0 0 10px 15px;
}
div.vio-text {
padding:0 0 10px 15px;
}
div.vio-note {
color:#999999;
padding:0 0 10px 15px;
}
div.vio-submit {
padding:10px 0 10px 0;
}
div.info-head {
padding:5px 7px 5px 7px;
border-style:solid;
border-width:0 0 1px 0;
border-color:#CCCCCC;
background-color:#eeeeee;
}
div.noborder{
border-style:solid;
border-color:#CCCCCC;
border-width:0 0 0 0;
}
div.info-body {
padding:7px;
}
div.info-msg {
margin:0 0 7px 0;
}
div.news-head {
padding:5px 7px 5px 7px;
border-style:solid;
border-width:0 0 1px 0;
border-color:#CCCCCC;
background-color:#eeeeee;
}
div.news-body {
padding:7px;
}
div.news-h1 {
margin:7px 7px 0 7px;
padding:7px;
border-style:solid;
border-width:3px;
border-color:#91C900;
}
div.news-h2 {
padding:0 0 3px 7px;
border-style:solid;
border-width:0 0 1px 4px;
border-color:#91C900;
}
img.news-memo {
margin:0 10px 5px 0;
border-style:solid;
border-width:1px;
border-color:#CCCCCC;
}
div.info-h2 {
padding:0 0 3px 7px;
border-style:solid;
border-width:0 0 1px 4px;
border-color:#91C900;
}
div.num-box{
background-color:#cccccc;
margin:0 30px;
}
td.tit-star{
background-color:#e9f8c3;
}
img.help{
border-style:solid;
border-width:2px;
border-color:#ffffff;
}
div.list{
padding:0 0 5px 0;
}
div.star-det{
padding:5px 0 5px 0;
}
img.sc{
border-style:solid;
border-width:1px;
border-color:#cccccc;
}
td.border {
background-color: #82c300;
}
div.border {
border-style: solid;
border-width: 0 0 5px 0;
border-color: #82c300;
}
div.border-c {
border-style: solid;
border-width: 0 0 2px 0;
border-color: #82c300;
}
td.space {
background-color: #82c300;
color: #82c300;
}
td.tabon {
color: #82c300;
}
td.taboff {
background-color: #82c300;
color: #ffffff;
}
td.tabpager {
background-color: #82c300;
color: #ffffff;
}
div.on {
padding: 1px 6px 3px 6px;
}
span.border {
color: #b2db59;
}
span.border-gray {
color: #cccccc;
}
a.taboff {
color: #ffffff;
}
div.comme {
padding: 3px 3px 3px 12px;
color: #b2db59;
}
span.text {
color: #333333;
}
td.gray {
background-color: #f2f2f2;
}
div.message {
width:226px;
margin:7px 7px 2px 7px;
padding:5px;
border-style:solid;
border-width:1px;
border-color:#BCCDED;
background-color:#E5EEFE;
}
div.error-message {
width:226px;
margin:7px 7px 2px 7px;
padding:5px;
border-style:solid;
border-width:1px;
border-color:#F5C8A7;
background-color:#FFEED8;
color:#9B2E2E;
}
div.ok-message {
width:226px;
margin:7px 7px 2px 7px;
padding:5px;
border-style:solid;
border-width:1px;
border-color:#C5DABA;
background-color:#E3F9DB;
color:#517B29;
}
div.guide-h2 {
padding:0 0 3px 7px;
border-style:solid;
border-width:0 0 1px 4px;
border-color:#66ccff;
}
div.guide-h3 {
padding:3px 3px 3px 3px;
background-color:#66ccff;
color: #ffffff;
}
div.select-t {
color: #66ccff;
padding: 0 0 3px 0;
}
div.select-b {
padding:5px 3px 5px 3px;
border-style: solid;
border-width: 1px 1px 1px 1px;
border-color: #99ccff;
background-color: #ffffff;
}
span.border-s {
color: #99ccff;
}
span.color {
color: #ffffff;
}
div.credit {
padding:5px 7px 5px 7px;
background-color:#eeeeee;
}
div.rule-tit {
background-color: #82c300;
color: #ffffff;
padding: 3px 3px 3px 3px;
}
div.rule-ind {
margin: 0 0 0 10px;
}
div.hr-prof {
border-style:solid;
border-width:0 0 3px 0;
border-color:transparent;
}
table.send {
margin: 5px 0 0 0 ;
}
div.icon {
border-style: solid;
border-width: 1px 1px 1px 1px;
border-color: #cccccc;
}
td.username {
height:20px;
}
td.mystatus {
}
div.prev {
padding: 1px 0 5px 0;
}
div.next {
padding: 5px 0 1px 0;
}
div.prof-det{
padding: 0 5px 0 5px;
}
div.catch {
margin: 5px 5px 5px 5px;
padding: 5px 5px 5px 5px;
border-style: solid;
border-width: 2px 2px 2px 2px;
border-color: #ffffff;
}
a.still {
color: #ffffff;
}
div.head {
margin: 0px 0 0 0;
}
div.send {
margin: 0px 10px 3px 11px;
}
div.link {
margin: 0px 10px 0 11px;
}
img.button {
margin: 5px 0 0 0;
}
td.theme {
margin: 0 0 0 3px;
}
div.trial-h1 {
margin: 5px 0 5px 0;
padding:3px;
border-style:solid;
border-width:3px;
border-color:#91C900;
}
div.mar-b10{
margin:0 0 10px 0;
}
div.cam1{
margin:7px 7px 0 7px;
padding:7px;
background-color: #ff2828;
color: #ffffff;
}
div.cam2{
margin:0 7px 0 7px;
padding:7px;
border-style:solid;
border-width: 2px 2px 2px 2px;
border-color: #ff2828;
}
table.xmas2009{
margin: 0 10px 0 11px;
background-color: #c70606;
color: #ffffff;
}
div.yellow {
margin: 0 11px 0 11px;
background-color:#ffe800;
}
div.sttr_mes {
width:226px;
margin:7px 7px 0px 7px;
padding:5px;
border-style:solid;
border-width:1px;
border-color:#92cb22;
background-color:#ffffff;
}
div.sttr_gacha {
width:226px;
margin:7px 7px 0px 7px;
padding:5px;
border-style:solid;
border-width:1px;
border-color:#ea475c;
background-color:#ffffff;
}
div.compsp {
width:226px;
margin:7px 7px 0px 7px;
padding:5px;
border-style:solid;
border-width:1px;
border-color:#ffe800;
background-color:#fff9b7;
}
div.sttr_war {
width:226px;
margin:7px 7px 0px 7px;
padding:5px;
border-style:solid;
border-width:1px;
border-color:#F5C8A7;
background-color:#FFEED8;
color:#9B2E2E;
}
div.sttr_price {
background-color:#FF9933;
color: #ffffff;
}
div.sttr_item {
width:226px;
margin:0px 7px 0px 7px;
padding:5px;
border-style:solid;
border-width:1px;
border-color:#92cb22;
background-color:#ffffff;
}
div.sttr_theme {
width:226px;
margin:0px 7px 3px 7px;
padding:5px;
border-style:solid;
border-width:0px 1px 1px 1px;
border-color:#92cb22;
background-color:#ffffff;
}
div.sttr_back {
width:226px;
margin:0px 7px 0px 7px;
}
div.gift_l {
margin: 0 11px 0 11px;
border-style:solid;
border-width:0 2px 0px 2px;
border-color:#ff5252;
}
div.gift_h {
margin: 0 11px 0 11px;
border-style:solid;
border-width:0 2px 0px 2px;
border-color:#ffd616;
}
img.shop_icon {
margin:0 1px 1px 0;
}
div.help_guide {
border-style:solid;
border-width:0 1px 1px 1px;
border-color:#ffac3e;
}
div.guide-head {
color: #ffffff;
background-color: #5abcea;
}
div.guide-title {
color: #ffffff;
background-color: #5abcea;
}
div.guide-main {
border-style:solid;
border-width:0 1px 1px 1px;
border-color:#5abcea;
}
div.green-title {
color: #ffffff;
background-color: #91C900;
}
div.green-main {
border-style:solid;
border-width:0 1px 1px 1px;
border-color:#91C900;
}
table.method{
border-style:solid;
border-width:1px;
border-color:#cccccc;
}
div.search {
background-color: #eeeeee;
border-style: solid;
border-width: 1px;
border-color:#cccccc;
}
td.keyboard {
background-color: #eeeeee;
}
table.key-tab{
margin: 0 6px 0 6px;
}
div.keyout {
margin: 0 7px 0 7px;
border-style: solid;
border-width: 0 1px 1px 1px;
border-color:#cccccc;
}
div.on-ja {
border-style: solid;
border-width: 1px 1px 0 1px;
border-color:#cccccc;
}
div.off-en {
border-style: solid;
border-width: 1px 1px 0 0;
border-color:#cccccc;
}
div.off-aa {
border-style: solid;
border-width: 1px 1px 0 0;
border-color:#cccccc;
}
table.camp-detail {
border-style: solid;
border-width: 1px;
border-color:#cccccc;
}
table.center {
margin: 0 15px 0 16px;
}
div.codeborder {
border-style: solid;
border-width:0 1px 1px 1px;
border-color:#82c300;
}
div.codeprev {
border-style: solid;
border-width:1px;
border-color:#82c300;
}
td.code {
background-color:#ffffff;
}
table.codetab {
border-style: solid;
border-width: 1px 1px 0 1px;
border-color:#82c300;
}
div.codetab {
border-style: solid;
border-width: 0 1px 1px 1px;
border-color:#82c300;
background-color:#ffffff;
}
div.c_tab2 {
border-style: solid;
border-width: 1px 1px 1px 1px;
border-color:#82c300;
background-color:#ffffff;
}
div.topic {
border-style:solid;
border-width:1px;
border-color:#fff273;
background-color:#fff8b2;
}
div.icon-green {
border-style: solid;
border-width: 1px 1px 1px 1px;
border-color: #82c300;
}
div.p-block {
border-style:solid;
border-width:1px;
border-color:#000000;
color:#000000;
background-color:#ffffff;
}
div.clstar-help{
background-color:#ffffff;
color:#82c300;
}
div.ugo4th{
border-style:solid;
border-width:1px;
border-color:#c4260f;
background-color:#d52515;
}
+808
View File
@@ -0,0 +1,808 @@
@charset "UTF-8";
span.url{
text-decoration:underline;
}
span.comptxt {
color:#ff8a00;
}
span.star0 {
color:#fdc556;
}
span.star1 {
color:#138200;
}
span.star2 {
color:#ff455c;
}
span.star3 {
color:#00b0f9;
}
span.star4 {
color:#a411b9;
}
span.star0c {
color:#fdc556;
}
span.star1c {
color:#138200;
}
span.star2c {
color:#ff455c;
}
span.star3c {
color:#00b0f9;
}
span.star4c {
color:#a411b9;
}
span.orange{
color: #ff8d45;
}
span.green {
color: #82c300;
}
span.gray{
color: #666666;
}
span.white {
color:#FFFFFF;
}
html {
margin:0;
padding:0;
}
body {
color:#333333;
margin:0;
padding:0;
}
div.title {
margin:0 7px 0 7px;
padding:7px 5px 7px 5px;
border-style:solid;
border-width:0 0 1px 0;
border-color:#CCCCCC;
}
div.description {
margin:0 7px 0 7px;
padding:7px 5px 7px 5px;
border-style:solid;
border-width:0 0 1px 0;
border-color:#CCCCCC;
}
div.hr {
border-style:solid;
border-width:0 0 1px 0;
border-color:#CCCCCC;
}
div.hr-tab {
border-style:solid;
border-width:0 0 1px 0;
border-color:#82c300;
}
span.timestamp {
color:#999999;
}
a.timestamp {
color:#999999;
}
a.violation {
color:#333333;
}
div.box {
padding:7px;
border-style:solid;
border-width:1px;
border-color:#CCCCCC;
background-color:#FFFFFF;
}
div.more {
margin:7px 0 0 0;
}
div.pager {
padding:5px;
}
div.num {
margin:5px;
padding:5px;
border-style:solid;
border-width:1px;
border-color:#CCCCCC;
background-color:#FFFFFF;
}
span.new {
color: #cc0000;
}
span.price {
color: #92cb22;
}
span.date {
color: #cccccc;
}
table.detail{
margin:0 7px 0 7px;
}
table.fullsize {
margin:0;
}
div.item-term {
padding:3px 0 3px 5px;
}
div.item-value {
padding:3px 5px 3px 0;
}
div.item-text {
padding:3px 5px 3px 15px;
}
div.item-tcom {
padding: 3px 5px 0 5px;
}
div.item-com {
padding: 0 5px 0 5px;
}
div.td-body {
padding:3px 5px 3px 5px;
}
div.comlist {
background-color:#FFFFFF;
}
div.comment-text {
padding:3px 5px 5px 15px;
}
div.comment-memo {
padding:0 0 0 15px;
}
div.staff {
color:#FFFFFF;
background-color:#1a1a1a;
}
a.staffnam {
color:#FFFFFF;
}
div.notice {
width:226px;
margin:7px 7px 3px 7px;
padding:5px;
border-style:solid;
border-width:1px;
border-color:#BCCDED;
background-color:#E5EEFE;
}
div.colorstar {
margin:7px 0 7px 0;
}
div.code-box{
width:226px;
margin:7px 0 0 0;
padding:5px;
border-style:solid;
border-width:1px;
border-color:#BCCDED;
background-color:#E5EEFE;
}
div.code-data{
margin:7px 0 7px 0;
}
div.mail-reply {
width:226px;
margin:7px 7px 2px 7px;
padding:5px;
border-style:solid;
border-width:1px;
border-color:#BCCDED;
background-color:#E5EEFE;
}
div.lett_txt {
margin: 0 11px 0 11px;
border-style:solid;
border-width:0 2px 0 2px;
border-color:#92d300;
background-color:#ffffff;
}
div.lett_to {
margin: 0 11px 0 11px;
background-color:#92d300;
color:#ffffff;
padding: 1px 0 6px 5px;
}
div.pad0{
padding: 0 0 0 0;
}
div.pad5t{
padding: 5px 0 0 0;
}
div.pad5b{
padding: 0 0 5px 0;
}
div.pad1b{
padding: 0 0 1px 0;
}
div.pad2b{
padding: 0 0 2px 0;
}
div.pad2{
padding: 2px 2px 2px 2px;
}
div.pad5{
padding: 5px 5px 5px 5px;
}
div.pad0-5{
padding: 0 5px 0 5px;
}
td.pad2{
padding: 2px 2px 2px 2px;
}
div.pad3-5{
padding: 3px 5px 3px 5px;
}
div.lett_from{
padding: 3px 11px 3px 0;
}
div.pad11{
padding: 11px 11px 11px 11px;
}
div.pad5-11{
padding: 5px 11px 5px 11px;
}
div.pad10b{
padding: 0 0 10px 0;
}
div.pad20b{
padding: 0 0 20px 0;
}
div.mar0-7{
margin: 0px 7px 0px 7px;
}
div.mar0-11{
margin: 0px 11px 0px 11px;
}
div.mar0{
margin: 0px 0px 0px 0px;
}
div.mar5 {
margin: 5px 5px 5px 5px;
}
div.yaritori{
margin: 0 11px 0 11px;
background-color:#ffffff;
border-style:solid;
border-width:0 2px 0 2px;
border-color:#92d300;
}
div.gr-tit{
margin: 0 11px 0 11px;
background-color:#92d300;
color:#ffffff;
}
div.kadomaru{
margin: 0 11px 0 11px;
}
div.lett-note{
margin: 5px 11px 5px 11px;
padding:5px;
border-style:solid;
border-width:1px;
border-color:#92d300;
background-color:#ffffff;
}
div.pk{
background-color:#ff3ab7;
}
div.blue{
background-color:#3acfff;
}
div.gray{
background-color:#cccccc;
}
div.gray_box{
padding:5px;
border-style:solid;
border-width:1px;
border-color:#cccccc;
background-color:#ffffff;
}
div.vio-intro {
width:240px;
padding:7px 0 7px 7px;
}
div.vio-memo {
padding:0 0 10px 15px;
}
div.vio-text {
padding:0 0 10px 15px;
}
div.vio-note {
color:#999999;
padding:0 0 10px 15px;
}
div.vio-submit {
padding:10px 0 10px 0;
}
div.info-head {
padding:5px 7px 5px 7px;
border-style:solid;
border-width:0 0 1px 0;
border-color:#CCCCCC;
background-color:#eeeeee;
}
div.noborder{
border-style:solid;
border-color:#CCCCCC;
border-width:0 0 0 0;
}
div.info-body {
padding:7px;
}
div.info-msg {
margin:0 0 7px 0;
}
div.news-head {
padding:5px 7px 5px 7px;
border-style:solid;
border-width:0 0 1px 0;
border-color:#CCCCCC;
background-color:#eeeeee;
}
div.news-body {
padding:7px;
}
div.news-h1 {
margin:7px 7px 0 7px;
padding:7px;
border-style:solid;
border-width:3px;
border-color:#91C900;
}
div.news-h2 {
padding:0 0 3px 7px;
border-style:solid;
border-width:0 0 1px 4px;
border-color:#91C900;
}
img.news-memo {
margin:0 10px 5px 0;
border-style:solid;
border-width:1px;
border-color:#CCCCCC;
}
div.info-h2 {
padding:0 0 3px 7px;
border-style:solid;
border-width:0 0 1px 4px;
border-color:#91C900;
}
div.num-box{
background-color:#cccccc;
margin:0 30px;
}
td.tit-star{
background-color:#e9f8c3;
}
img.help{
border-style:solid;
border-width:2px;
border-color:#ffffff;
}
div.list{
padding:0 0 5px 0;
}
div.star-det{
padding:5px 0 5px 0;
}
img.sc{
border-style:solid;
border-width:1px;
border-color:#cccccc;
}
td.border {
background-color: #82c300;
}
div.border {
border-style: solid;
border-width: 0 0 5px 0;
border-color: #82c300;
}
div.border-c {
border-style: solid;
border-width: 0 0 2px 0;
border-color: #82c300;
}
td.space {
background-color: #82c300;
color: #82c300;
}
td.tabon {
color: #82c300;
}
td.taboff {
background-color: #82c300;
color: #ffffff;
}
td.tabpager {
background-color: #82c300;
color: #ffffff;
}
div.on {
padding: 1px 6px 3px 6px;
}
span.border {
color: #b2db59;
}
span.border-gray {
color: #cccccc;
}
a.taboff {
color: #ffffff;
}
div.comme {
padding: 3px 3px 3px 12px;
color: #b2db59;
}
span.text {
color: #333333;
}
td.gray {
background-color: #f2f2f2;
}
div.message {
width:226px;
margin:7px 7px 2px 7px;
padding:5px;
border-style:solid;
border-width:1px;
border-color:#BCCDED;
background-color:#E5EEFE;
}
div.error-message {
width:226px;
margin:7px 7px 2px 7px;
padding:5px;
border-style:solid;
border-width:1px;
border-color:#F5C8A7;
background-color:#FFEED8;
color:#9B2E2E;
}
div.ok-message {
width:226px;
margin:7px 7px 2px 7px;
padding:5px;
border-style:solid;
border-width:1px;
border-color:#C5DABA;
background-color:#E3F9DB;
color:#517B29;
}
div.guide-h2 {
padding:0 0 3px 7px;
border-style:solid;
border-width:0 0 1px 4px;
border-color:#66ccff;
}
div.guide-h3 {
padding:3px 3px 3px 3px;
background-color:#66ccff;
color: #ffffff;
}
div.select-t {
color: #66ccff;
padding: 0 0 3px 0;
}
div.select-b {
padding:5px 3px 5px 3px;
border-style: solid;
border-width: 1px 1px 1px 1px;
border-color: #99ccff;
background-color: #ffffff;
}
span.border-s {
color: #99ccff;
}
span.color {
color: #ffffff;
}
div.credit {
padding:5px 7px 5px 7px;
background-color:#eeeeee;
}
div.rule-tit {
background-color: #82c300;
color: #ffffff;
padding: 3px 3px 3px 3px;
}
div.rule-ind {
margin: 0 0 0 10px;
}
div.hr-prof {
border-style:solid;
border-width:0 0 3px 0;
border-color:transparent;
}
table.send {
margin: 5px 0 0 0 ;
}
div.icon {
border-style: solid;
border-width: 1px 1px 1px 1px;
border-color: #cccccc;
}
td.username {
height:20px;
}
td.mystatus {
}
div.prev {
padding: 1px 0 5px 0;
}
div.next {
padding: 5px 0 1px 0;
}
div.prof-det{
padding: 0 5px 0 5px;
}
div.catch {
margin: 5px 5px 5px 5px;
padding: 5px 5px 5px 5px;
border-style: solid;
border-width: 2px 2px 2px 2px;
border-color: #ffffff;
}
a.still {
color: #ffffff;
}
div.head {
margin: 0px 0 0 0;
}
div.send {
margin: 0px 10px 3px 11px;
}
div.link {
margin: 0px 10px 0 11px;
}
img.button {
margin: 5px 0 0 0;
}
td.theme {
margin: 0 0 0 3px;
}
div.trial-h1 {
margin: 5px 0 5px 0;
padding:3px;
border-style:solid;
border-width:3px;
border-color:#91C900;
}
div.mar-b10{
margin:0 0 10px 0;
}
div.cam1{
margin:7px 7px 0 7px;
padding:7px;
background-color: #ff2828;
color: #ffffff;
}
div.cam2{
margin:0 7px 0 7px;
padding:7px;
border-style:solid;
border-width: 2px 2px 2px 2px;
border-color: #ff2828;
}
table.xmas2009{
margin: 0 10px 0 11px;
background-color: #c70606;
color: #ffffff;
}
div.yellow {
margin: 0 11px 0 11px;
background-color:#ffe800;
}
div.sttr_mes {
width:226px;
margin:7px 7px 0px 7px;
padding:5px;
border-style:solid;
border-width:1px;
border-color:#92cb22;
background-color:#ffffff;
}
div.sttr_gacha {
width:226px;
margin:7px 7px 0px 7px;
padding:5px;
border-style:solid;
border-width:1px;
border-color:#ea475c;
background-color:#ffffff;
}
div.compsp {
width:226px;
margin:7px 7px 0px 7px;
padding:5px;
border-style:solid;
border-width:1px;
border-color:#ffe800;
background-color:#fff9b7;
}
div.sttr_war {
width:226px;
margin:7px 7px 0px 7px;
padding:5px;
border-style:solid;
border-width:1px;
border-color:#F5C8A7;
background-color:#FFEED8;
color:#9B2E2E;
}
div.sttr_price {
background-color:#FF9933;
color: #ffffff;
}
div.sttr_item {
width:226px;
margin:0px 7px 0px 7px;
padding:5px;
border-style:solid;
border-width:1px;
border-color:#92cb22;
background-color:#ffffff;
}
div.sttr_theme {
width:226px;
margin:0px 7px 3px 7px;
padding:5px;
border-style:solid;
border-width:0px 1px 1px 1px;
border-color:#92cb22;
background-color:#ffffff;
}
div.sttr_back {
width:226px;
margin:0px 7px 0px 7px;
}
div.gift_l {
margin: 0 11px 0 11px;
border-style:solid;
border-width:0 2px 0px 2px;
border-color:#ff5252;
}
div.gift_h {
margin: 0 11px 0 11px;
border-style:solid;
border-width:0 2px 0px 2px;
border-color:#ffd616;
}
img.shop_icon {
margin:0 1px 1px 0;
}
div.help_guide {
border-style:solid;
border-width:0 1px 1px 1px;
border-color:#ffac3e;
}
div.guide-head {
color: #ffffff;
background-color: #5abcea;
}
div.guide-title {
color: #ffffff;
background-color: #5abcea;
}
div.guide-main {
border-style:solid;
border-width:0 1px 1px 1px;
border-color:#5abcea;
}
div.green-title {
color: #ffffff;
background-color: #91C900;
}
div.green-main {
border-style:solid;
border-width:0 1px 1px 1px;
border-color:#91C900;
}
table.method{
border-style:solid;
border-width:1px;
border-color:#cccccc;
}
div.search {
background-color: #eeeeee;
border-style: solid;
border-width: 1px;
border-color:#cccccc;
}
td.keyboard {
background-color: #eeeeee;
}
table.key-tab{
margin: 0 6px 0 6px;
}
div.keyout {
margin: 0 7px 0 7px;
border-style: solid;
border-width: 0 1px 1px 1px;
border-color:#cccccc;
}
div.on-ja {
border-style: solid;
border-width: 1px 1px 0 1px;
border-color:#cccccc;
}
div.off-en {
border-style: solid;
border-width: 1px 1px 0 0;
border-color:#cccccc;
}
div.off-aa {
border-style: solid;
border-width: 1px 1px 0 0;
border-color:#cccccc;
}
table.camp-detail {
border-style: solid;
border-width: 1px;
border-color:#cccccc;
}
table.center {
margin: 0 15px 0 16px;
}
div.codeborder {
border-style: solid;
border-width:0 1px 1px 1px;
border-color:#82c300;
}
div.codeprev {
border-style: solid;
border-width:1px;
border-color:#82c300;
}
td.code {
background-color:#ffffff;
}
table.codetab {
border-style: solid;
border-width: 1px 1px 0 1px;
border-color:#82c300;
}
div.codetab {
border-style: solid;
border-width: 0 1px 1px 1px;
border-color:#82c300;
background-color:#ffffff;
}
div.c_tab2 {
border-style: solid;
border-width: 1px 1px 1px 1px;
border-color:#82c300;
background-color:#ffffff;
}
div.topic {
border-style:solid;
border-width:1px;
border-color:#fff273;
background-color:#fff8b2;
}
div.icon-green {
border-style: solid;
border-width: 1px 1px 1px 1px;
border-color: #82c300;
}
div.p-block {
border-style:solid;
border-width:1px;
border-color:#000000;
color:#000000;
background-color:#ffffff;
}
div.clstar-help{
background-color:#ffffff;
color:#82c300;
}
div.ugo4th{
border-style:solid;
border-width:1px;
border-color:#c4260f;
background-color:#d52515;
}
+1
View File
@@ -0,0 +1 @@
body{background:#eee9f3;color:#2c2431}.container{background:#f6f2f8}.title{background:#6d4c82;color:#fff;padding:4px}.subtitle{font-weight:bold;color:#5b3f6d;padding:4px 0}.notice,.notice2{background:#e1d5e8;border:1px solid #b7a1c4;padding:5px}.comment{padding:4px}.detail th{color:#5b3f6d}.detail td{text-align:right}a{color:#4f6f00}
+20
View File
@@ -0,0 +1,20 @@
from twisted.web import resource
from DB import Database
from reximemo import dsi_url, flipnote_buttons, make_menu, pagination_buttons, query_int
class PyResource(resource.Resource):
isLeaf = True
def render_GET(self, request):
page = query_int(request, "page", 1)
total = Database.count_flipnotes()
rows = Database.list_flipnotes(page=page, per_page=50)
pager = pagination_buttons(request, "allflipnotes.uls", page, total)
prev = [b for b in pager if b["label"].startswith("Previous")]
nxt = [b for b in pager if b["label"].startswith("Next")]
request.setHeader(b"content-type", b"text/plain")
return make_menu(
layout=(2, 1), title="Browse", subtitle_top="All Flipnotes",
left="Flipnotes", right=str(total), buttons=prev + flipnote_buttons(request, rows) + nxt,
corner={"label": "Post", "url": dsi_url(request, "ch/1.post")},
)
+52
View File
@@ -0,0 +1,52 @@
from twisted.web import resource
from DB import Database
from hatena import NotFound, as_text, client_ip
from reximemo import current_account, dialog, dsi_url, flipnote_buttons, html_page, make_menu
class PyResource(resource.Resource):
isLeaf = False
def getChild(self, name, request):
text = as_text(name)
base, dot, ext = text.partition(".")
if not dot or not base.isdigit() or ext not in {"ugo", "uls", "htm", "post"}:
return NotFound
channel = Database.get_channel(int(base))
return ChannelResource(int(base), ext) if channel else NotFound
def render(self, request):
request.setResponseCode(403); return b""
class ChannelResource(resource.Resource):
isLeaf = True
def __init__(self, channel_id, ext):
super().__init__(); self.channel_id = channel_id; self.ext = ext
def render_GET(self, request):
channel = Database.get_channel(self.channel_id)
if self.ext in {"ugo", "uls"}:
rows = Database.list_flipnotes(channel_id=self.channel_id, limit=50)
request.setHeader(b"content-type", b"text/plain")
return make_menu(
layout=(2,1), title=channel["title"], subtitle_top="Channel", subtitle_bottom=channel["description"],
left="Flipnotes", right=str(Database.count_flipnotes(channel_id=self.channel_id)),
buttons=flipnote_buttons(request, rows), corner={"label":"Post", "url":dsi_url(request, f"ch/{self.channel_id}.post")},
)
if self.ext == "htm":
return html_page(request, channel["title"], '<div class="title">%s</div><p>%s</p><p><a href="%s">Browse</a></p>' % (channel["title"], channel["description"], dsi_url(request, f"ch/{self.channel_id}.uls")))
request.setResponseCode(405); return b""
def render_POST(self, request):
if self.ext != "post":
request.setResponseCode(405); return b""
data = request.content.read()
account = current_account(request)
try:
result = Database.AddFlipnote(data, str(self.channel_id), account["id"] if account else None, client_ip(request))
except Exception:
result = False
if not result:
return dialog(request, "Unable to post this Flipnote. It may already exist or be invalid.")
return b""
+38
View File
@@ -0,0 +1,38 @@
from twisted.web import resource
from DB import Database
from hatena import NotFound, as_text, request_args
from reximemo import comment_npf
class PyResource(resource.Resource):
isLeaf = False
def getChild(self, name, request):
text = as_text(name)
base, dot, ext = text.partition(".")
if not dot or not base.isdigit() or ext not in {"npf", "ppm"}:
return NotFound
return CommentFile(int(base), ext) if Database.get_comment(int(base)) else NotFound
class CommentFile(resource.Resource):
isLeaf = True
def __init__(self, cid, ext):
super().__init__(); self.cid = cid; self.ext = ext
def render_GET(self, request):
if self.ext == "ppm":
data = Database.comment_ppm(self.cid)
if data is None:
return NotFound.render(request)
request.setHeader(b"content-type", b"application/octet-stream")
return data
args = request_args(request)
try: w = max(1, min(256, int(args.get("w", ["128"])[0])))
except ValueError: w = 128
try: h = max(1, min(192, int(args.get("h", ["64"])[0])))
except ValueError: h = 64
data = comment_npf(self.cid, w, h)
if data is None:
return NotFound.render(request)
request.setHeader(b"content-type", b"application/octet-stream")
return data
+61
View File
@@ -0,0 +1,61 @@
import html
from twisted.web import resource
from DB import Database
from hatena import NotFound, as_text
from reximemo import dsi_url, flipnote_buttons, html_page, make_menu
class PyResource(resource.Resource):
isLeaf = False
def getChild(self, name, request):
try:
room_id = int(as_text(name))
except ValueError:
return NotFound
return CreatorNode(room_id) if Database.get_creator_room(room_id) else NotFound
class CreatorNode(resource.Resource):
isLeaf = False
def __init__(self, room_id):
super().__init__(); self.room_id = room_id
def getChild(self, name, request):
text = as_text(name)
aliases = {"room.ugo":"room.uls", "movies.ugo":"movies.uls"}
text = aliases.get(text, text)
if text in {"profile.htm", "room.uls", "movies.uls"}:
return CreatorLeaf(self.room_id, text)
return NotFound
class CreatorLeaf(resource.Resource):
isLeaf = True
def __init__(self, room_id, action):
super().__init__(); self.room_id = room_id; self.action = action
def render_GET(self, request):
room = Database.get_creator_room(self.room_id)
if not room:
return NotFound.render(request)
notes = Database.list_creator_flipnotes(self.room_id, limit=50)
if self.action in {"room.uls", "movies.uls"}:
request.setHeader(b"content-type", b"text/plain")
return make_menu(
layout=(2,1), title=room["display_name"], subtitle_top="Creator's Room",
left="Flipnotes", right=str(len(notes)), buttons=flipnote_buttons(request, notes),
corner={"label":"Post", "url":dsi_url(request, "ch/1.post")},
)
profile = (
'<div class="title" align="center">%s</div>'
'<div class="notice2" align="center">Creator\'s Room</div>'
'<table width="226" class="detail">'
'<tr><th>Flipnotes</th><td>%d</td></tr>'
'<tr><th>Identity</th><td>%s</td></tr>'
'</table><p><a href="%s">View Flipnotes</a></p>'
) % (
html.escape(room["display_name"]), len(notes),
"Account" if room.get("account_id") else "Guest/IP",
html.escape(dsi_url(request, f"creator/{self.room_id}/movies.uls"), quote=True),
)
return html_page(request, room["display_name"], profile)
+1
View File
@@ -0,0 +1 @@
RQBuAGcAbABpAHMAaAA= en
1 RQBuAGcAbABpAHMAaAA= en
+8
View File
@@ -0,0 +1,8 @@
from twisted.web import resource
from reximemo import make_menu
class PyResource(resource.Resource):
isLeaf = True
def render_GET(self, request):
request.setHeader(b"content-type", b"text/plain")
return make_menu(layout=(4,), title="Inbox", subtitle_bottom="Notifications are not included in OSE.", buttons=[])
+30
View File
@@ -0,0 +1,30 @@
from twisted.web import resource
from DB import Database
from reximemo import current_account, dsi_url, flipnote_buttons, make_menu, placeholder_icon
class PyResource(resource.Resource):
isLeaf = True
def render_GET(self, request):
rows = Database.list_flipnotes(limit=8)
account = current_account(request)
buttons = [
{"label": "Browse Flipnotes", "url": dsi_url(request, "allflipnotes.uls"), "icon_ntft": placeholder_icon("browse"), "embed_name": "browse.ntft"},
{"label": "Account", "url": dsi_url(request, "sa/account.htm"), "icon_ntft": placeholder_icon("account"), "embed_name": "account.ntft"},
]
room = Database.room_for_account(account["id"]) if account else Database.room_for_ip(__import__('hatena').client_ip(request))
if room:
buttons.append({"label": "Creator's Room", "url": dsi_url(request, f"creator/{room['id']}/profile.htm"), "icon_ntft": placeholder_icon("room"), "embed_name": "room.ntft"})
buttons.extend(flipnote_buttons(request, rows))
request.setHeader(b"content-type", b"text/plain")
return make_menu(
layout=(2, 1),
title="RexiMemo OSE",
subtitle_top="Open Source Edition",
subtitle_bottom="Proxy build",
left="Recent",
right=str(Database.count_flipnotes()),
buttons=buttons,
corner={"label": "Post", "url": dsi_url(request, "ch/1.post")},
)
+185
View File
@@ -0,0 +1,185 @@
from __future__ import annotations
import html
from twisted.web import resource
from DB import Database
from Hatenatools import TMB
from hatena import NotFound, as_text, client_ip, request_headers
from reximemo import current_account, dialog, dsi_url, forward, html_page, keyboard_value
class PyResource(resource.Resource):
isLeaf = False
def getChild(self, name, request):
fsid = as_text(name).upper()
return CreatorNode(fsid) if Database.CreatorExists(fsid) else NotFound
def render(self, request):
request.setResponseCode(403); return b""
class CreatorNode(resource.Resource):
isLeaf = False
def __init__(self, fsid):
super().__init__(); self.fsid = fsid
def getChild(self, name, request):
text = as_text(name)
if "." in text:
base, ext = text.rsplit(".", 1)
if ext in {"ppm", "tmb", "info", "htm", "star", "dl", "reply"} and Database.FlipnoteExists(self.fsid, base):
return FlipnoteFile(self.fsid, base, ext)
if Database.FlipnoteExists(self.fsid, text):
return FlipnoteActionNode(self.fsid, text)
return NotFound
class FlipnoteActionNode(resource.Resource):
isLeaf = False
def __init__(self, fsid, filename):
super().__init__(); self.fsid = fsid; self.filename = filename
def getChild(self, name, request):
if as_text(name) == "keyboard.kbd":
return TextComment(self.fsid, self.filename)
return NotFound
class TextComment(resource.Resource):
isLeaf = True
def __init__(self, fsid, filename):
super().__init__(); self.fsid = fsid; self.filename = filename
def render_POST(self, request):
fn = Database.get_flipnote(self.fsid, self.filename)
if not fn:
return NotFound.render(request)
account = current_account(request)
try:
Database.add_text_comment(
fn["id"], keyboard_value(request), ip_address=client_ip(request),
account_id=(account["id"] if account else None),
)
except ValueError as exc:
return dialog(request, str(exc))
forward(request, dsi_url(request, f"movie/{self.fsid}/{self.filename}.htm"))
return b"OK"
def render_GET(self, request):
request.setResponseCode(405); return b""
class FlipnoteFile(resource.Resource):
isLeaf = True
def __init__(self, fsid, filename, ext):
super().__init__(); self.fsid = fsid; self.filename = filename; self.ext = ext
def render_GET(self, request):
fn = Database.get_flipnote(self.fsid, self.filename)
if not fn:
return NotFound.render(request)
if self.ext == "ppm":
Database.AddView(self.fsid, self.filename)
request.setHeader(b"content-type", b"application/octet-stream")
return Database.GetFlipnotePPM(self.fsid, self.filename)
if self.ext == "tmb":
request.setHeader(b"content-type", b"application/octet-stream")
return Database.GetFlipnoteTMB(self.fsid, self.filename)
if self.ext == "info":
request.setHeader(b"content-type", b"text/plain")
return b"0\n0\n"
if self.ext == "dl":
Database.AddDownload(self.fsid, self.filename)
return b"OK"
if self.ext == "star":
headers = request_headers(request)
try:
amount = int(headers.get("x-hatena-star-count", "1"))
except ValueError:
amount = 1
Database.AddStar(self.fsid, self.filename, amount)
return b"Success"
if self.ext == "htm":
return details_page(request, fn)
request.setResponseCode(405); return b""
def render_POST(self, request):
fn = Database.get_flipnote(self.fsid, self.filename)
if not fn:
return NotFound.render(request)
if self.ext == "reply":
data = request.content.read()
tmb = TMB().Read(data)
if not tmb:
return dialog(request, "That mini Flipnote is invalid.")
if int(getattr(tmb, "FrameCount", 1)) != 1:
return dialog(request, "Mini Flipnote comments must contain one frame.")
account = current_account(request)
try:
Database.add_memo_comment(
fn["id"], data, ip_address=client_ip(request),
account_id=(account["id"] if account else None),
)
except ValueError as exc:
return dialog(request, str(exc))
forward(request, dsi_url(request, f"movie/{self.fsid}/{self.filename}.htm"))
return b"OK"
request.setResponseCode(405); return b""
def details_page(request, fn):
try:
tmb = TMB().Read(Database.GetFlipnoteTMB(fn["creator_fsid"], fn["filename"]))
except Exception:
tmb = None
creator_name = fn.get("creator_name") or (getattr(tmb, "Username", "") if tmb else "Creator")
creator_url = dsi_url(request, f"creator/{fn['creator_room_id']}/profile.htm")
ppm_url = dsi_url(request, f"movie/{fn['creator_fsid']}/{fn['filename']}.ppm")
star_url = dsi_url(request, f"movie/{fn['creator_fsid']}/{fn['filename']}.star")
reply_url = dsi_url(request, f"movie/{fn['creator_fsid']}/{fn['filename']}.reply")
text_url = dsi_url(request, f"movie/{fn['creator_fsid']}/{fn['filename']}/keyboard.kbd")
extra = (
'<meta name="upperlink" content="%(ppm)s">'
'<meta name="savebutton" content="%(ppm)s">'
'<meta name="playcontrolbutton" content="">'
'<meta name="starbutton" content="%(star)s">'
'<meta name="commentbutton" content="%(reply)s">'
) % {
"ppm": html.escape(ppm_url, quote=True),
"star": html.escape(star_url, quote=True),
"reply": html.escape(reply_url, quote=True),
}
comments = Database.list_comments(fn["id"], limit=30)
comment_html = []
for c in comments:
if c["type"] == "memo":
npf = dsi_url(request, f"comment/{c['id']}.npf?w=128&h=64")
ppm = dsi_url(request, f"comment/{c['id']}.ppm")
content = '<a href="%s"><img src="%s" width="128" height="64"></a>' % (html.escape(ppm, quote=True), html.escape(npf, quote=True))
else:
content = html.escape(c.get("text_content") or "")
comment_html.append(
'<div class="comment"><strong>%s</strong><br>%s</div><div class="hr"></div>' % (
html.escape(c.get("creator_name") or "Guest"), content,
)
)
body = (
'<div class="title">%(title)s</div>'
'<table width="226" class="detail">'
'<tr><th>Creator</th><td><a href="%(creator_url)s">%(creator)s</a></td></tr>'
'<tr><th>Stars</th><td>%(stars)d</td></tr>'
'<tr><th>Views</th><td>%(views)d</td></tr>'
'</table>'
'<p><a href="%(ppm)s">Play Flipnote</a></p>'
'<p><a href="%(text)s">Text Comment</a></p>'
'<div class="hr"></div><div class="subtitle">Comments</div>%(comments)s'
) % {
"title": html.escape(fn.get("title") or "Untitled Flipnote"),
"creator_url": html.escape(creator_url, quote=True),
"creator": html.escape(creator_name),
"stars": int(fn.get("stars") or 0),
"views": int(fn.get("views") or 0),
"ppm": html.escape(ppm_url, quote=True),
"text": html.escape(text_url, quote=True),
"comments": "".join(comment_html) or '<div class="notice">No comments yet.</div>',
}
return html_page(request, fn.get("title") or "Flipnote", body, extra)
+58
View File
@@ -0,0 +1,58 @@
import html
from twisted.web import resource
from DB import Database
from hatena import NotFound, as_text, client_ip
from reximemo import current_account, dialog, dsi_url, forward, html_page, keyboard_value
class PyResource(resource.Resource):
isLeaf = False
def getChild(self, name, request):
action = as_text(name)
if action in {"account.htm", "login.kbd", "register.kbd", "logout.htm"}:
return AccountLeaf(action)
return NotFound
class AccountLeaf(resource.Resource):
isLeaf = True
def __init__(self, action):
super().__init__(); self.action = action
def render_GET(self, request):
account = current_account(request)
if self.action == "logout.htm":
Database.logout_ip(client_ip(request))
forward(request, dsi_url(request, "index.ugo"))
return b"OK"
if self.action != "account.htm":
request.setResponseCode(405); return b""
if account:
room = Database.room_for_account(account["id"])
room_link = '<p><a href="%s">Creator\'s Room</a></p>' % html.escape(dsi_url(request, f"creator/{room['id']}/profile.htm"), quote=True) if room else '<p>Your Creator\'s Room is created after your first post.</p>'
body = '<div class="title">Account</div><p>Signed in as <strong>%s</strong>.</p>%s<p><a href="%s">Sign out</a></p>' % (html.escape(account["username"]), room_link, html.escape(dsi_url(request, "sa/logout.htm"), quote=True))
else:
body = '<div class="title">Account</div><p>OSE uses one simple IP login. Enter <strong>username:password</strong> in the keyboard.</p><p><a href="%s">Sign in</a></p><p><a href="%s">Register</a></p>' % (html.escape(dsi_url(request, "sa/login.kbd"), quote=True), html.escape(dsi_url(request, "sa/register.kbd"), quote=True))
return html_page(request, "Account", body)
def render_POST(self, request):
if self.action not in {"login.kbd", "register.kbd"}:
request.setResponseCode(405); return b""
value = keyboard_value(request)
if ":" not in value:
return dialog(request, "Enter username:password")
username, password = value.split(":", 1)
if self.action == "login.kbd":
account = Database.verify_account(username, password)
if not account:
return dialog(request, "Sign in failed.", 403)
Database.login_ip(client_ip(request), account["id"])
else:
try:
aid = Database.create_account(username, password)
Database.login_ip(client_ip(request), aid)
except ValueError as exc:
return dialog(request, str(exc))
forward(request, dsi_url(request, "sa/account.htm"))
return b"OK"
+1
View File
@@ -0,0 +1 @@
[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[� � � � � � � � � � � � � � � � � � � � � � � � � � � � �[�[�[�[� � � � � � � � � � � � � � � � � � � � � � � � � � � � �[�[�[�[� � �[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[� � �[�[�[�[� � �[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[� � �[�[�[�[� � �[�[�[�[�[�[�[�[�[�[�-�-�-�-�[�[�[�[�[�[�[�[�[�[� � �[�[�[�[� � �[�[�[�[�[�[�[�[�[�-�-�-�-�-�-�[�[�[�[�[�[�[�[�[� � �[�[�[�[� � �[�[�[�[�[�[�[�[�-�-�-�-�-�-�-�-�[�[�[�[�[�[�[�[� � �[�[�[�[� � �[�[�[�[�[�[�[�-�-�-�-�-�-�-�-�-�-�[�[�[�[�[�[�[� � �[�[�[�[� � �[�[�[�[�[�[�[�-�-�-�-�-�-�-�-�-�-�[�[�[�[�[�[�[� � �[�[�[�[� � �[�[�[�[�[�[�[�-�-�-�-�-�-�-�-�-�-�[�[�[�[�[�[�[� � �[�[�[�[� � �[�[�[�[�[�[�[�-�-�-�-�-�-�-�-�-�-�[�[�[�[�[�[�[� � �[�[�[�[� � �[�[�[�[�[�[�[�[�-�-�-�-�-�-�-�-�[�[�[�[�[�[�[�[� � �[�[�[�[� � �[�[�[�[�[�[�[�[�[�-�-�-�-�-�-�[�[�[�[�[�[�[�[�[� � �[�[�[�[� � �[�[�[�[�[�[�[�[�[�[�-�-�-�-�[�[�[�[�[�[�[�[�[�[� � �[�[�[�[� � �[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[� � �[�[�[�[� � �[�[�[�[�-�-�-�-�-�-�-�-�-�-�-�-�-�-�-�-�[�[�[�[� � �[�[�[�[� � �[�[�[�[�-�-�-�-�-�-�-�-�-�-�-�-�-�-�-�-�[�[�[�[� � �[�[�[�[� � �[�[�[�[�-�-�-�-�-�-�-�-�-�-�-�-�-�-�-�-�[�[�[�[� � �[�[�[�[� � �[�[�[�[�-�-�-�-�-�-�-�-�-�-�-�-�-�-�-�-�[�[�[�[� � �[�[�[�[� � �[�[�[�[�-�-�-�-�-�-�-�-�-�-�-�-�-�-�-�-�[�[�[�[� � �[�[�[�[� � �[�[�[�[�-�-�-�-�-�-�-�-�-�-�-�-�-�-�-�-�[�[�[�[� � �[�[�[�[� � �[�[�[�[�-�-�-�-�-�-�-�-�-�-�-�-�-�-�-�-�[�[�[�[� � �[�[�[�[� � �[�[�[�[�-�-�-�-�-�-�-�-�-�-�-�-�-�-�-�-�[�[�[�[� � �[�[�[�[� � �[�[�[�[�-�-�-�-�-�-�-�-�-�-�-�-�-�-�-�-�[�[�[�[� � �[�[�[�[� � �[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[� � �[�[�[�[� � �[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[� � �[�[�[�[� � � � � � � � � � � � � � � � � � � � � � � � � � � � �[�[�[�[� � � � � � � � � � � � � � � � � � � � � � � � � � � � �[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�
+1
View File
@@ -0,0 +1 @@
[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[� � � � � � � � � � � � � � � � � � � � � � � � � � � � �[�[�[�[� � � � � � � � � � � � � � � � � � � � � � � � � � � � �[�[�[�[� � �[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[� � �[�[�[�[� � �[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[� � �[�[�[�[� � �[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[� � �[�[�[�[� � �[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[� � �[�[�[�[� � �[�[�[�-�-�-�-�-�-�-�-�-�-�-�-�-�-�-�-�-�-�[�[�[� � �[�[�[�[� � �[�[�[�-�-�-�-�-�-�-�-�-�-�-�-�-�-�-�-�-�-�[�[�[� � �[�[�[�[� � �[�[�[�-�-�-�-�-�-�-�-�-�-�-�-�-�-�-�-�-�-�[�[�[� � �[�[�[�[� � �[�[�[�-�-�-�-�-�-�-�-�-�-�-�-�-�-�-�-�-�-�[�[�[� � �[�[�[�[� � �[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[� � �[�[�[�[� � �[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[� � �[�[�[�[� � �[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[� � �[�[�[�[� � �[�[�[�-�-�-�-�-�-�-�-�-�-�-�-�-�-�-�-�-�-�[�[�[� � �[�[�[�[� � �[�[�[�-�-�-�-�-�-�-�-�-�-�-�-�-�-�-�-�-�-�[�[�[� � �[�[�[�[� � �[�[�[�-�-�-�-�-�-�-�-�-�-�-�-�-�-�-�-�-�-�[�[�[� � �[�[�[�[� � �[�[�[�-�-�-�-�-�-�-�-�-�-�-�-�-�-�-�-�-�-�[�[�[� � �[�[�[�[� � �[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[� � �[�[�[�[� � �[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[� � �[�[�[�[� � �[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[� � �[�[�[�[� � �[�[�[�-�-�-�-�-�-�-�-�-�-�-�-�-�-�-�-�-�-�[�[�[� � �[�[�[�[� � �[�[�[�-�-�-�-�-�-�-�-�-�-�-�-�-�-�-�-�-�-�[�[�[� � �[�[�[�[� � �[�[�[�-�-�-�-�-�-�-�-�-�-�-�-�-�-�-�-�-�-�[�[�[� � �[�[�[�[� � �[�[�[�-�-�-�-�-�-�-�-�-�-�-�-�-�-�-�-�-�-�[�[�[� � �[�[�[�[� � �[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[� � �[�[�[�[� � �[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[� � �[�[�[�[� � � � � � � � � � � � � � � � � � � � � � � � � � � � �[�[�[�[� � � � � � � � � � � � � � � � � � � � � � � � � � � � �[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�
Binary file not shown.
+1
View File
@@ -0,0 +1 @@
[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[� � � � � � � � � � � � � � � � � � � � � � � � � � � � �[�[�[�[� � � � � � � � � � � � � � � � � � � � � � � � � � � � �[�[�[�[� � �[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[� � �[�[�[�[� � �[�[�[�[�[�[�[�[�[�[�[�[� �[�[�[�[�[�[�[�[�[�[�[� � �[�[�[�[� � �[�[�[�[�[�[�[�[�[�[�[� � � �[�[�[�[�[�[�[�[�[�[� � �[�[�[�[� � �[�[�[�[�[�[�[�[�[� � � � � � � �[�[�[�[�[�[�[�[� � �[�[�[�[� � �[�[�[�[�[�[�[�[� � � � � � � � � �[�[�[�[�[�[�[� � �[�[�[�[� � �[�[�[�[�[�[� � � � � � � � � � � � �[�[�[�[�[�[� � �[�[�[�[� � �[�[�[�[�[� � � � � � � � � � � � � � �[�[�[�[�[� � �[�[�[�[� � �[�[�[� � � � � � � � � � � � � � � � � � �[�[�[� � �[�[�[�[� � �[�[� � � � � � � � � � � � � � � � � � � � �[�[� � �[�[�[�[� � �[�[�[�-�-�-�-�-�-�-�-�-�-�-�-�-�-�-�-�-�-�[�[�[� � �[�[�[�[� � �[�[�[�-�-�-�-�-�-�-�-�-�-�-�-�-�-�-�-�-�-�[�[�[� � �[�[�[�[� � �[�[�[�-�-�-�-�-�-�-�-�-�-�-�-�-�-�-�-�-�-�[�[�[� � �[�[�[�[� � �[�[�[�-�-�-�-�-�-�-�-�-�-�-�-�-�-�-�-�-�-�[�[�[� � �[�[�[�[� � �[�[�[�-�-�-�-�-�-�-�-�-�-�-�-�-�-�-�-�-�-�[�[�[� � �[�[�[�[� � �[�[�[�-�-�-�-�-�-�-�-�-�-�-�-�-�-�-�-�-�-�[�[�[� � �[�[�[�[� � �[�[�[�-�-�-�-�-�-�-�-�-�-�-�-�-�-�-�-�-�-�[�[�[� � �[�[�[�[� � �[�[�[�-�-�-�-�-�-�-�-�-�-�-�-�-�-�-�-�-�-�[�[�[� � �[�[�[�[� � �[�[�[�-�-�-�-�-�-�-�-�-�-�-�-�-�-�-�-�-�-�[�[�[� � �[�[�[�[� � �[�[�[�-�-�-�-�-�-�-�-�-�-�-�-�-�-�-�-�-�-�[�[�[� � �[�[�[�[� � �[�[�[�-�-�-�-�-�-�-�-�-�-�-�-�-�-�-�-�-�-�[�[�[� � �[�[�[�[� � �[�[�[�-�-�-�-�-�-�-�-�-�-�-�-�-�-�-�-�-�-�[�[�[� � �[�[�[�[� � �[�[�[�-�-�-�-�-�-�-�-�-�-�-�-�-�-�-�-�-�-�[�[�[� � �[�[�[�[� � �[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[� � �[�[�[�[� � �[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[� � �[�[�[�[� � � � � � � � � � � � � � � � � � � � � � � � � � � � �[�[�[�[� � � � � � � � � � � � � � � � � � � � � � � � � � � � �[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�[�